I can help you get started. The easiest way to verify if its a valid equation is to try to convert it and throw an exception if you run into a problem with it. If you haven't learned about exceptions yet, then one way to go is to traverse through the equation and push each left paren onto a stack, and then remove one each time you find a right paren. If there are parens left in the stack when you're done, or if the stack is empty and you find a right paren, then it isn't balanced.
As far as converting goes, here is a good algorithm for converting postfix to infix. You hopefully shouldn't have too much trouble converting it to java code. You'll have to add a little more to process parenthetical portions.
Good luck!
leverin4
Junior Poster in Training
79 posts since Apr 2008
Reputation Points: 10
Solved Threads: 4
I would read the whole equation in as a String and use
String.charAt(int i)
inside a for-loop to step through it character by character. You would need six if statements inside said for-loop for, 2 for each type of bracket. However, if you aren't restricted from altering the original equation, you could use that
{ 2 * 3 + ( 4 / [ 8 - 6 ] ) } == ( 2 * 3 + ( 4 / ( 8 - 6 ) ) )
You could run through the equation once and convert curly and square brackets to their paren counterparts. If doing this doesn't violate the rules in the assignment, it'll definitely make your life easier. This way you'd only need two if statements when verifying if its a balanced equation, and you could do it all with one stack.
Alternatively, if you can't change the brace types, you'll probably need 3 stacks; 1 for each type of bracket.
Keep in mind, verifying if it's a valid equation also requires you to make sure every operator you come across is a valid operator too.
leverin4
Junior Poster in Training
79 posts since Apr 2008
Reputation Points: 10
Solved Threads: 4
What if there are say three left parentheses on the stack, but then a right bracket appears? How would the program know that the bracket doesn't match, since there are only parentheses on the stack?
edit: If a closed bracket is encountered when a '(' is on the top of the stack, then you know already that you have an error. So when you see a '}', you should attempt to pop a '{' off of the top of the stack. If the element on top of the stack is not a '{', then you have an error. (If this doesn't make sense, read the rest of my post first, then re-read this).Should each character be tested every time to see if it's a "closer" and if it matches with whatever "opener" is on top of the stack?
When you see an open bracket, you should push an open bracket onto the stack. When you see a closed bracket, you should pop an open bracket from the stack. If you see a closed bracket, and there are no open brackets left on the stack, then you have just encountered an error. After analyzing an entire set of brackets, your stack should be empty, indicating that the same number of open and closed brackets were seen, in an acceptable order. (For example, {{}}}{ has three open brackets and three closed brackets, but it is not in an acceptable order. If your program encountered {{}}}{ it should do the following:
Stack after seeing { = {
Stack after seeing {{ = {{
Stack after seeing {{} = {
Stack after seeing {{}} = (empty)
Stack after seeing {{}}} = error, because you just saw a closed bracket, but it is impossible to pop an open bracket from the stack.
In a nutshell, your job is to push "open" (brackets, parens, curly braces) onto the stack when you see an "open" (bracket, paren, curly brace), and then to pop the top of the stack when you see a closed type (so if you see a closed brace, you pop the top element of the stack). Then you have to check the element that you just popped off of the stack to make sure it is an open brace.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
You can't use three separate stacks because consider the following input:
{(})
That input isn't valid, and should result in an error. But if you use separate stacks for each symbol, it will appear legitimate and it won't cause an error. And I'll take a look at your code momentarily.
edit: It looks like you're using separate stacks, which I do not think is correct for the reason I listed above. The order in which the braces/brackets/parens are seen is very important, and using different stacks does not keep track of the order they were seen in. You should implement one stack where you use a few comparisons to make sure things are valid.
You'd have the following comparisons:
1) the case where you just saw a }. You'd have code similar to this pseudocode:
typeOfBrace = readInNextBrace();
if (typeOfBrace == '}' or typeOfBrace == ')' or typeOfBrace == ']') //You have to make sure its a closed type before you pop.
topElement = stack.pop();
if (typeOfBrace == '}'){
if (topElement == '{') // there's no error!
} else //there's an error, do something!
2) the case where you just saw a ]. Pseudocode:
typeOfBrace = readInNextBrace();
if (typeOfBrace == '}' or typeOfBrace == ')' or typeOfBrace == ']') //You have to make sure its a closed type before you pop.
topElement = stack.pop();
if (typeOfBrace == ']'){
if (topElement == '[') // there's no error!
} else //there's an error, do something!
3) There is also the case where you just saw a ), but since the code is so similar to what is above, I won't repost it again. Oh, and obviously, you only want to do the first part of the code that I posted once, not twice. (The part up to and including stack.pop() should only be done one time, then you should have a few if statements afterwards to check the types).
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
I updated my last post, you should take a look. And at this point, I'd recommend that you first develop the code for the parentheses then. After you get that working, then add in logic for the brackets and curly braces. It would be pointless to help you complete the separate stacks solution, since the algorithm itself is flawed.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Your syntax is wrong, that is all. .
if ((myStack.empty()==true) && (line.charAt(j) == ')')||(line.charAt(j) == ']')||(line.charAt(j) == '}')) {
Should be:
if ((myStack.empty()==true) && ((line.charAt(j) == ')')||(line.charAt(j) == ']')||(line.charAt(j) == '}'))) {
Because you want to check "if the stack is empty and any one of }, ], or ) is seen, then . . ." but look at your if statement more closely: It will be executed any time a ']' or a '}' is seen, or whenever both the stack is empty and a ')' is seen.
And haha, your error is ironic if that is it, considering the project assignment is about grouping of operators, which was the cause of your error. (But no offense, I've made similar mistakes before)
:)
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Whether or not the stack is empty for an invalid equation depends on your implementation. However, if in your implementation you "pop" an element off of the stack and then compare it to the next '}' or']' or ')', your stack would be empty even if there was an invalid condition.
(Ex: {) ):
Stack after seeing { = {
See ')' and pop top of stack. Top of stack, '{', is not the correct element for ')'. Therefore your stack is empty because you just popped the only element on it, but you have an error condition.
I'm not saying you don't have an error in your stack class, but you can easily come up with an error when your stack is empty if you are popping the elements off the stack before comparing them. If you post all of your classes again (w/ whatever your most up to date code is) I'll look at them later and help you figure out what's wrong.
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Cool, glad you got it to work. If there's anything you still have trouble with let me know and I'll help you out later today. I'm going to do a really fun Iphone program so I'll probably be off until then though.
Oh, and mark as solved if you don't have any more ?s
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
Would I need to check each individual character of the equation against each possible operator? (+, -, *, /, etc.) or is there a much simpler way?
Yes, you'd need to compare against each operator. Java uses Unicode, not ASCII, but even if you used the Unicode values, you'd be doing the same thing as comparing against each operator (unless the operators are right next to each other in the Unicode table, in which case, you could say something like "if (charImComparing >=120 && charImComparing <= 125)".
BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354