Ensure parenthesis are balanced? - java

I am tasked to create a function that checks if a number of small "(" and big "[" parentheses and closes properly. For example...
(()) [] ([])[(())]
...is correct, but...
() [(])
...is incorrect.
Any advice on how to start approaching this problem? The use of recursive functions is prohibited.
This is what I have so far:
{
int nr_ap_x = 0; // fie x - "("
int nr_ap_y = 0; // fie y - ")"
boolean corect = true;
for (int i=0; i < sir.length; i++)
{
if (sir[i].compareTo("(") == 0) nr_ap_x++;
else
if (sir[i].compareTo(")") == 0) nr_ap_y++;
if (nr_ap_x < nr_ap_y) corect = false;
}
if (nr_ap_x != nr_ap_y) corect = false;
if (corect) System.out.println("Parantezele sunt inchise corect ! ");
else System.out.println("Parantezele NU sunt inchise corect ! ");
}

General outline of how to do this (assuming you have an array of strings each containing a parenthesis):
Create a stack which contains strings.
For each "(" or "[", push onto the stack.
For each ")" or "]", check if the top of the stack matches the type of parenthesis.
If it does, discard the top of the stack.
Otherwise, the parenthesis are mismatched.
If you have a non empty stack once all your strings run out, you also have mismatched parentheses.

Hint: keep a data structure containing the opening glyphs, and use and update it when a closing glyph appear.

Anything that's done with recursion can also be done with iteration. If you already know how to do it recursively then map it to a while loop. This is explained in Replace Recursion with Iteration.

You could use a deterministic finite automaton - http://en.wikipedia.org/wiki/Deterministic_finite-state_machine

Related

palindromeRearrangin CodeSignal hidden tests

I am trying to solve this . I passed 18 tests from 20 . 2 of them are hidden and I cant understand what are those 2 scenarios. Please tell me if you see something wrong here . I saw many solutions on the WEB, but I want to understand what is wrong with my own code.
For inputString = "aabb", the output should be
palindromeRearranging(inputString) = true.
We can rearrange "aabb" to make "abba", which is a palindrome.
Here is my code:
boolean palindromeRearranging(String str) {
Stack<Character> stack=new Stack<>();
for (int i = 0; i < str.length(); i++) {
if(stack.contains(str.charAt(i))){
stack.pop();
continue;
}
stack.push(str.charAt(i));
}
if(stack.size()>1) return false;
return true;
}
When you're by using condition stack.contains(str.charAt(i)),
find out that current checking character str.charAt(i) is already present in Stack,
you need to remove that particular repeating character instead of the last character present in Stack.
so only stack.pop() is a mistake in code.
One of those scenarios in my case :
"abcabc" . Should return true, but instead it returns false. I sorted the String first then my algorithm worked :)

Valid parentheses in Java

Code:
public static void main(String[] args) {
Arrays.asList("a+(b*c)-2-a", "(a+b*(2-c)-2+a)*2", "(a*b-(2+c)", "2*(3-a))", ")3+b*(2-c)(")
.stream().forEach((expression) -> {
if (replaceAll(expression, "[(]") == replaceAll(expression, "[)]")) {
System.out.println("correct");
} else {
System.out.println("incorrect");
}
});
}
private static int replaceAll(String word, String regex) {
int count = word.length() - word.replaceAll(regex, "").length();
return count;
}
I have to check if the expression is valid or not. What determine if an expression is valid or not are the parentheses. If it's self closed, is valid, otherwise, not.
My code is almost correct, it's printing:
correct
correct
incorrect
incorrect
correct
But it must print
correct
correct
incorrect
incorrect
incorrect -> the last expression isn't valid.
You need not only to check if the number of opening parentheses matches the number of closed, but also if each closing parenthesis goes after opening one which isn't "closed" yet:
static boolean checkParentheses(String s) {
int opened = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(')
opened++;
else if (s.charAt(i) == ')') {
if (opened == 0) // means that all parentheses are "closed" yet
return false;
opened--;
}
}
return opened == 0;
}
If you strictly need regex to be involved, do the following:
static boolean checkParentheses(String s) {
// capture a text starting with one opening parenthesis,
// ending with one closing and having no parentheses inside
Pattern p = Pattern.compile("\\([^()]*\\)");
Matcher m;
while ((m = p.matcher(s)).find())
s = m.replaceAll("");
return !(s.contains("(") || s.contains(")"));
}
Your issue is that it's not enough just to count parentheses; you also need to spot where a ')' comes too early. For example ")(" is not valid even though there are an equal number of opening and closing parentheses.
One approach is to keep a count. Start at zero. Each time you see '(', count++. Each time you see ')', count--.
After a decrement, if(count<0) the input is invalid.
At the end of input, if(count!0) the input is invalid.
It's been pointed out that this can't be done in a single regex. That's because a regex represents a finite state machine. count could in principle increase infinitely.
If you pick a maximum nesting depth, you can write a regex to check it. For example, for a maximum depth of 3:
x*(<x*(<x*(<x*>)*x*>)*x*>)*x*
(I've used 'x' instead of arbitrary chars here, for readability. Replace it with [^<>] to actually match other chars. I've also used <> instead of \(\) again for readability. The () here are for grouping.).
You can always make it work one level deeper by replacing the x* in the middle with x*(<x*>)*x* -- but you can never made a regex that doesn't stop working at a certain depth.
An alternative method is closer to what a real statement parser would do with nested structures: recurse. Something like (pseudocode):
def consumeBlock() {
switch(next char)
case end-of-input
throw error -- reached end of input inside some parentheses
case '('
consumeBlock() -- go down a nesting level
break;
case ')'
return -- go up a nesting level
default
It's an uninteresting character. Do nothing.
(a real parser compiler would do something more interesting)
}
Here consumeBlock() assumes you've just consumed a '(' and you intend to read until its pair.
Some of your inputs don't begin with a '(', so prime it by first appending a ')' to the end, as the pair to a "silent" ')' you're saying it's already consumed.
The pseudocode already shows that if you hit end-of-input mid-block, it's invalid input. Also if you are not at end-of-input when the top-level call to consumeBlock() returns, it's invalid input.
You could go through it char by char and using a counter to tell the parenthesis level in the statement.
boolean valid = true;
int level = 0;
for(int i=0; i < expr.length(); i++) {
if(expr.charAt(i) == '(') level++;
if(expr.charAt(i) == ')') level--;
if(level < 0) { // ) with no (
valid = false;
break;
}
}
if(level > 0) valid = false; // ( with no )
return valid; // true if level returned to 0

insert in for loop fails

I'm trying to insert in a for loop to a Stringbuilder but it crashes. This is my code
StringBuilder sb = new StringBuilder("This is a text");
for(int i = 0;i < sb.length();i++){
if(sb.charAt(i) == 't'){
sb.insert(i, 't');
}
}
Purpose of this is to double every 't'.
You are getting an OutOfMemoryError, because you don't skip the t character that you're doubling.
This is a text
^
This is a ttext
^
This is a tttext
^
This continues until you've run out of memory.
You must skip the t that you just added by incrementing i just after inserting the doubled t.
if (sb.charAt(i) == 't')
{
sb.insert(i, 't');
i++;
}
I suggest to use a StringBuilder and the string like this:
String currentText = "This is a text";
StringBuilder sb = new StringBuilder();
for(int i = 0; i < currentText.length(); i++){
sb.append(currentText.charAt(i));
if(currentText.charAt(i) == 't'){
sb.append('t');
}
}
With that solution, you will not have the problem with a never ending loop.
The problem you are having is the following.
Iterate through the list, from start to finish.
If you find a t add a t.
Two scenarios, either there is at least 1 t in the String or there are none. If there are none then all will work, the code does nothing. However if there is a t it will find that t add another t, the next character to check will now be... a t!. Infinite loop.
You can go around the problem by either by incrementing i (ì++) or by using continue.
Because when you find a t this instruction sb.insert(i, 't') add t in position i and previous t become in position i+1, so when i will increment in the end of for loop with i++ you deal another time with same letter t. so that will cause infinity loop.
To fix that you should increment i with i++ in if block like that:
if(sb.charAt(i) == 't'){
sb.insert(i, 't');
i++;
}

Arrays - square-free word

This is what the program should do:
The word, zatabracabrac, is not square free, since it has subword, abrac twice start-
ing at position 4 of the word.
We are not allowed to use strings, breaks or other complex stuff. I get the square and square not part but am unable to find its place. I think I went wrong some place like I can't figure it out.
public static void main(String[] args) {
// part (a) of the main
Scanner keyboard = new Scanner(System.in);
System.out.println("***************************");
System.out.println(" Part (a)");
System.out.println("***************************");
do{
System.out.println("Enter a word and then press enter:");
String str=keyboard.next();
char[] word = str.toCharArray();
isSquareFree(word);
System.out.println("Do you want to test another word? Press y for yes, or another key for no");
}while(keyboard.next().charAt(0)=='y');
public static void isSquareFree(char[] word){
int z = 0;
for(int i=0; i<word.length; i++){
for(int j=0; j<word.length-1;j++){
if (word[j] == word[j+1]){
z = 1;
j = word.length;
}
else{
z = 2;
}
}
}
if (z == 1){
System.out.println();
System.out.println("Not Square Free");
}
else{
System.out.println();
System.out.println("Square Free");
}
}
}
Downvotes on the question: this is not where you solve your homework... we all went through having homeworks and solved them (well, most of us), and that's partly why we're capable of helping you.
You're checking whether the word contains two consecutive characters which are the same.
That's not what you want, try another solution.
Here's why it does what I said above:
The outer for loop doesn't have an effect on the inner one, since i is not used inside
Index j and j+1 in the same iteration as a character and the next one
Other notes:
j = word.length is the same as break here, try using that, it stops your loop like the end condition was satisfied; read more: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/branch.html
For easier testing, you might want to use another main function containing only calls like isSquareFree("zatabracabrac".toCharArray());, even multiple ones to see multiple test results at once
This will greatly reduce the change-compile-run-check cycle's length.
You can use a debugger in an IDE (Eclipse or IntelliJ) to see what your program does.
Without debugging you can use println/print/printf calls to see how many iterations you have and what your values during those iterations.
Hints on solution:
As I see you're essentially looking for consecutive k-length subword duplicates
You phrased it right in the comment, the arbitrary length is giving it another level
At each position i try to look for a subword with length k which has a corresponding match starting at i + k (this helps the consecutive constraint)
k can be anything between a letter and half of the string (more than that is overkill since it cannot repeat twice)
I didn't code it, but it would be my first try
In your examples:
borborygmus
^=>
i
borborygmus
^=>
i+k
With k = 3 there is a match
zatabracabrac
^===>
i
zatabracabrac
^===>
i+k
With k = 5 there is a match

Stack, Parentheses Matching [duplicate]

This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 5 years ago.
So I'm working on some homework with PostFix and Infix Expressions. I'm running into a bit of a problem and can't seem to find where I'm having the issue. I can get the Infix to Postfix working...for the most part. Some of the equations I'm getting a ( or ) printed when I don't want it to be printed. Also when I have no matching parentheses I don't get an error like I want it to.
public String Infix(String equation) throws Exception{
Stack stack=new Stack();
boolean parensMatch=false;
int priority=0;
String temp="";
for(int i=0; i<equation.length(); i++){
char c=equation.charAt(i);
//if the character is equal to left paren, push
if(c=='('){
stack.push(c);
}
//if the character is equal to right paren, we start popping until we find a match
else if(c==')'){
try{
while(stack.peek()!='('){
temp+=stack.pop();
}
if(stack.peek()=='('){
char ch=stack.pop();
parensMatch=true;
}
if(parensMatch==false){
throw new Exception("Parens Not Match Error");
}
}catch(Exception e){
System.out.println(e);
}
parensMatch=false;
}
//if the character is equal to an operator, we do some extra work
//to figure out what is going to happen
else if(c=='+' || c=='-' || c=='*' || c=='/' || c=='^'){
char top=stack.peek();
if(top=='^')
priority=2;
else if(top=='*' || top=='/')
priority=1;
else
priority=0;
if(priority==2){
if(c=='*' || c=='/'){
temp+=stack.pop();
}
else if(c=='+' || c=='-'){
temp+=stack.pop();
}
else{
temp+=stack.pop();
}
}
else{
if(c=='*' || c=='/'){
temp+=stack.pop();
stack.push(c);
}
else if(c=='+' || c=='-'){
stack.push(c);
}
else{
stack.push(c);
}
}
}
//if the character is a space, we ignore it and move on
else if(c==' '){
;
}
//if the character is a letter, we add it to the string
else{
temp+=c;
}
}
int len = stack.size();
for (int j = 0; j < len; j++)
temp+=stack.pop();
return temp;
}
This is my Infix to Postfix method
(((A + B) - (C - D)) / (E - F)) This is one of the expressions that I need to solve, and AB+CD--(EF-/ is what I get when it prints to the screen. ((A is another, this one should give me an error but A(( is printed to the screen.
I have been running the debug for quite a while and can't seem to get anywhere.
Any help would be very helpful. I know it has something to with the code posted but I can't find the logic error. Thanks in advance!
So I added a new function to help with matching parens that I think will be useful. It takes the equation and just counts to see if they match or not.
public static int matchingParens(String equation){
int match=0;
for(int i=0; i<equation.length(); i++){
char c=equation.charAt(i);
if(c=='(')
match++;
else if(c==')')
match--;
else
;
}
return match;
}
To validate if parenthesis are all matched up, you can run through your String input of the math expression with a counter of initial value of 0, and if you find a (, increment your counter by 1, and if you find a ), decrement your counter by 1. If the counter ever reaches -1, break out, as it isn't a valid parenthesis match. In the end, you should have the counter's value as 0. If not, you have a mismatched parenthesis.
For the infix to postfix case, here's a standard algorithm:
Define a stack
Go through each character in the string
If it is between 0 to 9, append it to output string.
If it is left brace push to stack
If it is operator *,+,- or / then
If the stack is empty push it to the stack
If the stack is not empty then start a loop:
If the top of the stack has higher precedence
Then pop and append to output string
Else break
Push to the stack
If it is right brace then
While stack not empty and top not equal to left brace
Pop from stack and append to output string
Finally pop out the left brace.
Well I would like give you some "software engineering" tip, which in the end can solve your problem and you can learn a lot by doing it "nice".
Mathematical expression, no matter if you write them in pre, in, post order, looks always the same, if you store them in some tree structure.
Then, if you want to print that tree structure into String, you just go through the whole tree, and it varies only in the moment (and additional braces for some cases), when you write it to that string.
Preorder do it when you first go into that node, Inorder when you finished left child and Postorder, if you do it when you leaving that node.
My advice :
Class : Expression, UnaryExpression extends Expression, BinaryExpression extedns Expression and then you can make numbers and operators : Add extends BinaryExpression etc.
Then you should have class Tree, which stores the Expression root and it has methods printPreOrder(), printInOrder(), printPostOrder()
To create that tree, it would be really nice to use a Builder pattern which can be used like this :
public class Director {
private IExpressionBuilder builder;
public ArithmeticExpression construct(String text){
for (int i=0;i<text.length();i++){
if (text.charAt(i) == '+'){
builder.buildAddOperator();
}
...
}
}
And then you create concrete Builder classes, which look like this :
public class InOrderBuilder implements IExpressionBuilder {
public void buildAddOperator() {
...
}
....
}

Categories

Resources