开发者

Recognizing Parenthesis in an Infix to Postfix Conversion [duplicate]

This question already has answers here: Handling parenthesis while converting infix expressions to postfix expressions (2 answers) Closed 6 years ago.

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.

  1. 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() != '('){

  2. You'll also need to protect the theStack.pop(); right below there:

    if (!theStack.isEmpty()) {
        theStack.pop();
    }
    
  3. 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;
    }
    
  4. 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 of 43. :-)

Couple of style points:

  • As mentioned, use Character.isDigit(ch)
  • You should use a StringBuilder() so you can do postfix.append(ch) instead of building the string with many postfix + ch. [Shudder]
  • I'd make the postfix field local to the convert() 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;
        }
    }
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜