Recognizing Parenthesis in an Infix to Postfix Conversion [duplicate]
Here is a java class I had to make for my data structures class. I know that this is far from the best way to do the conversion, but it is off of the pseudo code he gave in class and is therefor what he is looking for. The only thing he left for us to figure out on our own was for how the algorithm recognizes parenthesis. The program runs just fine when I input an expression without them, but the minute I add parenthesis the program won't run, specifically, through some debugging, I found that the close parenthesis does this ")". I marked with comments where the actual parenthesis part of the method is. Thanks for 开发者_开发技巧the help!
public class InToPost {
private Stack theStack;
private String infix;
private String postfix = "";
public InToPost(String in) {
infix = in;
int stackSize = infix.length();
theStack = new Stack(stackSize);
}
public String convert(){
for (int i = 0; i < infix.length(); i++) {
char ch = infix.charAt(i);
if ((ch == '0') || (ch == '1') || (ch == '2') || (ch == '3') || (ch == '4') ||
(ch == '5') || (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9')) {
postfix = postfix + ch;
}
//check for parenthesis
else if (ch == ')'){
while (theStack.topStk() != '('){
int topStk = theStack.pop();
postfix = postfix + topStk;
}
theStack.pop();
} else {
while ((theStack.isEmpty() == false)&&(prcd(theStack.topStk(),ch) == true)){
char topSymb = theStack.pop();
postfix = postfix + topSymb;
}
theStack.push(ch);
}
}
while(theStack.isEmpty() == false){
char topSymb = theStack.pop();
postfix = postfix + topSymb;
}
return postfix;
}
public boolean prcd(char one, char two){
int onePrcd = 0;
int twoPrcd = 0;
if ((one == '+') || (one == '-')){
onePrcd = 1;
}
if ((two == '+') || (two == '-')){
twoPrcd = 1;
}
if ((one == '*') || (one == '/')){
onePrcd = 2;
}
if ((two == '*') || (two == '/')){
twoPrcd = 2;
}
if (one == '$') {
onePrcd = 3;
}
if (two == '$') {
twoPrcd = 3;
}
if (one == '(') {
onePrcd = 4;
}
if (two == '('){
twoPrcd = 4;
}
if (onePrcd >= twoPrcd){
return true;
} else {
return false;
}
}
public static void main(String[] args){
String input = "(2+3)*4";
String output;
InToPost theTrans = new InToPost(input);
output = theTrans.convert();
System.out.println("Postfix is " + output + '\n');
}
}
This was a fun exercise. You were pretty close but there are some bugs in here. I had to debug the code and twiddle a bit.
As @S.L. Barth mentioned, the
while (theStack.topStk() != '('){
line can cause a stack underflow. You'll need to change this to be:while (!theStack.isEmpty() && theStack.topStk() != '('){
You'll also need to protect the
theStack.pop();
right below there:if (!theStack.isEmpty()) { theStack.pop(); }
When you are checking the precedence from the top of the stack, you shouldn't put
'('
characters on the output:if (topSymb != '(') { postfix = postfix + topSymb; }
But the kicker bug is that you are unloading from the stack into an
int
when you are closing the')'
:int topStk = theStack.pop();
That should be changed to a char which outputs a+
instead of43
. :-)
Couple of style points:
- As mentioned, use
Character.isDigit(ch)
- You should use a
StringBuilder()
so you can dopostfix.append(ch)
instead of building the string with manypostfix + ch
. [Shudder] - I'd make the
postfix
field local to theconvert()
method to reduce scope. - It's considered bad form to say
== false
or== true
. Just drop the== true
and use the!
character for false:(!theStack.isEmpty()) && prcd(theStack.topStk(),ch)
I'd create a
charToPrecedence(char)
which uses a switch to return the value of each char. Much cleaner code.public boolean precident(char one, char two) { return (charToPrcd(one) >= charToPrcd(two)); } private int charToPrcd(char ch) { switch (ch) { case '+' : case '-' : return 1; case '*' : case '/' : return 2; case '$' : return 3; case '(' : return 4; default : return 0; } }
精彩评论