【问题标题】:Parsing of math expression gives wrong tree解析数学表达式给出错误的树
【发布时间】:2016-06-16 00:22:05
【问题描述】:

所以代码相当复杂,所以我试着做一些简洁的伪代码来涵盖最重要的问题。我正在尝试解析数学表达式。例如:1-5*(-2)+3 = 14

我使用的语法是:

expression = term   OR term+expression OR term-expression
term       = factor OR factor*term     OR factor/term
factor     = number OR -factor         OR (expression)

我已经写了一段代码来检查一个表达式是否遵循这个语法,它可以很好地检查表达式,但不能用于计算它。

伪代码如下:

double readExpression()
    number = readTerm()
    if token == +
        number2 = readExpression()
        return number + number2
    else if token == -
        number2 = readExpression()
        return number - number2
    else
        return number
...
(The code for readTerm() is identical to readExpression() in structure)
...
double readFactor()
    if token == number
        return number
    else if token == -
        number = readFactor()
        return (-1)*number
    else if token == (
        number = readExpression()
        return number
    else raise exception

如果我用这段代码进行上述计算,它会给我一棵看起来像这样的树:

所以无论如何,正如你们数学家现在已经弄清楚的那样,表达式应该给出 14 而不是树所暗示的 8。我注意到当表达式前面有减号时会出现问题,因为会影响整个右项我这个问题,而他们应该只影响中间项。

我已经疯狂地思考了好几个星期,并为此考虑了解决方案,并查看了其他代码等等。如果我自己浏览了很多关于树遍历和其他相关主题的链接,请不要向我扔一堆链接。

在这个阶段我能做什么?正如我所说,我的程序可以判断它是对还是错。所以现在我只需要解析一个正确的表达式。我应该写另一个类来解析正确的表达式吗?更容易吗?无论如何,我看不出该代码与此有何不同。

【问题讨论】:

    标签: java recursion syntax tree


    【解决方案1】:

    是的,我会解析方程式,看起来您错过了操作/解析顺序的关键部分。您需要额外检查双重否定。

    这里的关键因素是:在有两个相同运算符的情况下,总是首先执行最左边的操作。

    首先让我们缩小问题范围。

    这个1-5*(-2)+3 等于1--10+3

    现在,为了我们的目的,让我们为第一个运算符分配一个肯定的值,因为它有助于说明一个观点:

    1--10+3+1--10+3 相同

    现在,如果我们通过正确的解析器在哪里运行+1--10+3,我们会知道这个-- 等于+,但只有在以下情况下使用:

    +X--Y = X+Y

    所以现在我们的解析器将1--10+3 的原始表达式转换为1+10+3,我们知道它等于14。

    总而言之:是的,您需要一个解析器,但要特别注意 +X--Y 和 X+Y 的工作方式。

    也看看这个答案:https://stackoverflow.com/a/26227947/1270000

    【讨论】:

    • 它实际上与双重否定无关。它可以处理这些。 2-3*2+3 也被计算为 3*2=6 然后 6+3=9 然后 2-9=-7 这是错误的。它与语法有关....它看不到它应该从左到右添加或类似的东西。
    • 我查看了您提供的链接,与我的伪代码相比,我看不出该代码有任何逻辑差异; / 所以我不知道
    • 另外,该代码只评估,我的也这样做。我也想计算表达式。
    • 好吧,如果这不是问题,那么它可能只有一件事,那就是您的操作顺序:例如,这应该首先发生 +1--10 但您的代码显然忽略了从左到右的规则,而是在做-10 + 3。这可能只是您的代码没有备份并执行我们期望的从左到右操作的简单问题。可能值得粘贴更多代码,因为我认为您会发现它很简单,事后您会为之自责。
    • 补充我的最后一条评论:您如何以及在何处确定每个操作的顺序?应始终在每次单独计算之前完成,而不是在开始时进行单一评估。
    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-07
    相关资源
    最近更新 更多