识别中缀到后缀转换中的括号

时间:2011-10-06 03:39:46

标签: java infix-notation postfix-notation

这是我必须为我的数据结构类创建的java类。我知道这远非转换的最佳方式,但它取决于他在课堂上给出的伪代码,因此他正在寻找什么。他留给我们自己弄清楚的唯一一件事就是算法如何识别括号。当我输入没有它们的表达式时,程序运行得很好,但是当我添加括号时,程序将无法运行,具体来说,通过一些调试,我发现右括号执行了这个“)”。我用注释标记了方法的实际括号部分。谢谢你的帮助!

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');
    }  
}

1 个答案:

答案 0 :(得分:2)

这是一项有趣的练习。你很近,但这里有一些错误。我不得不调试代码并稍微调整一下。

  1. As @ S.L。 Barth提到,while (theStack.topStk() != '('){行可能导致堆栈下溢。您需要将其更改为:

    while (!theStack.isEmpty() && theStack.topStk() != '('){

  2. 您还需要保护位于其下方的theStack.pop();

    if (!theStack.isEmpty()) {
        theStack.pop();
    }
    
  3. 当您从堆栈顶部检查优先级时,不应在输出中放置'('个字符:

    if (topSymb != '(') {
        postfix = postfix + topSymb;
    }
    
  4. 踢球者错误是当您关闭int时,您正从堆栈卸载到')'int topStk = theStack.pop();那应该是更改为输出+而不是43的字符。 : - )

  5. 一些风格点:

    • 如上所述,请使用Character.isDigit(ch)
    • 您应该使用StringBuilder(),这样您就可以postfix.append(ch)而不是使用多个postfix + ch构建字符串。 [发抖]
    • 我将postfix方法设为convert()字段,以缩小范围。
    • == false== true是不好的形式。只需删除== true并将!字符用于false:(!theStack.isEmpty()) && prcd(theStack.topStk(),ch)
    • 即可
    • 我创建了一个charToPrecedence(char),它使用一个开关来返回每个char的值。更干净的代码。

      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;
          }
      }