首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java计算器-调车场

Java计算器-调车场
EN

Stack Overflow用户
提问于 2018-12-12 14:32:33
回答 1查看 2.5K关注 0票数 9

我试图实现迪克斯特拉算法 Shunting-yard来读取一个简单操作的数学方程(+-/*)。它基本上得到一个"infix“字符串,并将其转换为”后缀“字符串。

例如:输入-> "(3+5)*4-12"。输出:Queue[3,5,+,4, *,12,-]

当你从右到左阅读时,你会发现你需要从乘法4中减去12,再加上3和5。

我做得很对。我认为将队列解释为计算的最简单方法是使用递归,因此我提出了以下代码:

代码语言:javascript
复制
public static Expression newCalc(ArrayDeque<String> q)//q is the output of Shunting yard algo
{
    String tmp =q.pollLast();
    if(tmp.equals("*") || tmp.equals("/") || tmp.equals("+") || tmp.equals("-")) {
        Expression rightOperation = newCalc(q);
        Expression leftOperation = newCalc(q);
        if(tmp.equals("+")) 
            return new Plus(leftOperation,rightOperation);
        else if(tmp.equals("-"))
            return new Minus(leftOperation,rightOperation);
        else if(tmp.equals("*"))
            return new Mul(leftOperation,rightOperation);
        else if(tmp.equals("/"))
            return new Div(leftOperation,rightOperation);
        else
            return new Number(0);
    }
    else 
        return new Number(Double.parseDouble(tmp));

}

它适用于几乎任何字符串,但如下所示的字符串除外:

代码语言:javascript
复制
"(3+5)*4-12+1"

在调车场之后,队列输出为:[3,5,+,4, *,12,1,+,-]

问题在于,递归返回(3+5)*4 -(12+1),这是错误的,我无法解决这个问题(我知道我可以使用迭代解决方案,但我想了解如何使这个问题工作)。

谢谢。

编辑:

我的调车场

代码语言:javascript
复制
public static double calc(String expression){

    Stack<String> s = new Stack<String>();  
    ArrayDeque<String> q = new ArrayDeque<String>();
    StringBuilder sb = new StringBuilder(expression);
    String token = new String();

    while((token = atoi(sb)) != null) {
    //atoi is a method that extract the correct next token ,cut it it from the string and return it.
        if(token.equals("/")|| token.equals("-")|| token.equals("+")|| token.equals("*")) {
            while ((token.equals("-")||token.equals("+"))&&
                    !s.isEmpty()&&
                    ((s.peek().equals("*")||s.peek().equals("/"))))
                q.add(s.pop());
            s.push(token);
        }
        else if(token.equals("("))
            s.push(token);
        else if(token.equals(")"))
        {
            while(!s.peek().equals("("))
                q.add(s.pop());
            s.pop();    
        }       
        else 
        {
            q.add(token);
        }
    }
    while(!s.isEmpty()&&(s.peek().equals("/")||s.peek().equals("*")||s.peek().equals("+")||s.peek().equals("-")))
        q.add(s.pop());
    return Math.floor(newCalc(q).calculate()*1000)/1000;

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-13 15:01:06

正如@BillThe蜥蜴在这个问题的评论中所暗示的那样,递归是好的,问题在于我的分流场算法。代码的UML说,只有在一个操作符优先于另一个操作符的情况下,才会替换两个操作符,但是他们忘了提到,当两个操作符之间没有优先级时,我也需要保留操作符的原始顺序(特别是+和-,这在不同的执行顺序上有差异)。这就解决了问题:

代码语言:javascript
复制
while ((token.equals("-")||token.equals("+"))&& 
        !s.isEmpty()&&
        ((!s.peek().equals("(")&&!s.peek().equals(")")))) // I've changed this line
    q.add(s.pop());
s.push(token);

谢谢你的帮助。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53745300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档