【问题标题】:Handling parenthesis while converting infix expressions to postfix expressions在将中缀表达式转换为后缀表达式时处理括号
【发布时间】:2013-11-12 07:37:55
【问题描述】:

我正在使用 Java 开发一个项目,该项目需要我将中缀表达式转换为后缀表达式。我目前可以使用这种方法将中缀表达式转换为后缀,只要它们不包含括号,但我不知道如何处理括号。

基本上,我有两个堆栈,其中包含称为“令牌”的对象。 Token 是一个包装类,它包含一个字符串,该字符串可以是数字、变量(被评估为数字,等待用户输入)、运算符(运算符具有与其关联的优先级,以便我的方法可以确定如何处理 '+'、'-'、'*' 和 '/' 之间的操作顺序)或括号(括号有办法确定它是开括号还是闭括号)。

我应该如何处理括号?多层括号呢?

public String toPostFix() {
    StringBuilder postfixstr = new StringBuilder();

    Stack<Token> in_fix = new Stack<>();
    Stack<Token> post_fix = new Stack<>();

    for (int i = tokens.length - 1; i >= 0; i--) {
        t = new Token(tokens[i]);
        in_fix.push(t);
    }

    //there are still tokens to process
    while (!in_fix.empty()) {
        //is a number
        if (in_fix.peek().type == 1) {     
            postfixstr.append(in_fix.pop().toString());
        } 

        //is an operator and the stack is empty
        else if (in_fix.peek().type == 3 && post_fix.empty()) {   
            post_fix.push(in_fix.pop());
        } 

        // is an operator that has higher priority than the operator on the stack
        else if (in_fix.peek().type == 3 && in_fix.peek().isOperator() > post_fix.peek().isOperator()) {
            post_fix.push(in_fix.pop());
        } 

        // is an operator that has lower priority than the operator on the stack
        else if (in_fix.peek().type == 3 && in_fix.peek().isOperator() <= post_fix.peek().isOperator()) {
            postfixstr.append(post_fix.pop());
            post_fix.push(in_fix.pop());
        } 

        //puts the rest of the stack onto the output string
        if (in_fix.empty()) {
            while (!post_fix.empty()) {
                postfixstr.append(post_fix.pop());
            }
        }
    }

    return postfixstr.toString();
}

【问题讨论】:

  • 您所拥有的或多或少是 Dijkstra 调车场算法,但没有括号处理。
  • 有趣。我现在正在研究这方面的一些文献!

标签: java postfix-notation infix-notation


【解决方案1】:

您需要将左括号压入堆栈,并在遇到右括号时像这样处理堆栈:

// opening (
if (in_fix.peek().type == 4) {   
    post_fix.push(in_fix.pop());
}
//closing )
if(in_fix.peek().type == 5){
    while(!(post_fix.isEmpty() || post_fix.peek().type == 4)){
         postfixstr.append(post_fix.pop());
    }
    if (post_fix.isEmpty())
        ; // ERROR - unmatched )
    else
        post_fix.pop(); // pop the (
    in_fix.pop(); // pop the )
} 

【讨论】:

  • @downvoter 这个算法是 Edsger Dijkstra 在 1961 年发明的,这是它的一部分的准确表示。您的里程明显不同。
  • 绝对不是我!哈哈。
  • @dg_no_9 et al. 这个笑话让我无法理解。线程中唯一正确的答案,它有一个反对意见?
  • 我猜你和我的答案相似,我认为你的答案太正确了,这就是为什么我没有像你对我的那样对你投反对票。 :)
  • 非常感谢!这完美地工作。 =) 我会帮忙投票,但我的声誉还不够高!哈哈哈
【解决方案2】:

试试这个方法:

    //opening Parenthesis 
        if (in_fix.peek().type == 4) {   
                    post_fix.push(in_fix.pop());
        }
        //closing Parenthesis 
        if(in_fix.peek().type == 5){
             //Till opening parenthesis encountered in stack, append operators to postfix. and pop parenthesis and do not append to post_fix.
             while(post_fix.peek().type!=4){
                 postfixstr.append(post_fix.pop());
             }
            //finally pop left parenthesis from post_fix stack.
            post_fix.pop();
        } 

【讨论】:

  • 看起来不对。 while 条件将如何变化?
  • 对不起,我对 in_fix 堆栈和 post_fix 堆栈感到困惑。现在我已经编辑了。谢谢(你的)信息。 :)
  • 还是不对。这只会将括号附加到后缀。应该是!= 4。您还需要检查缺少的右括号(即空堆栈),然后弹出 (。我建议您查找它。
  • 这不是代码的完全工作副本,我只是想给他/她一个想法。这就是为什么我提到了cmets中的逻辑。
  • 半小时前我在 cmets 中命名了该算法,在您发布您的答案之前,我自己几乎没有“得到一些想法”,而且我在投反对票之前给了您一些提示,它是也几乎没有。但足够了。您最近的修改仍然不够充分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-05-02
相关资源
最近更新 更多