【问题标题】:Infix expression evaluation [closed]中缀表达式求值
【发布时间】:2012-08-25 12:57:49
【问题描述】:

我想在 C++ 中评估(不转换)中缀表达式。如果你有算法,甚至是这种算法的实现(可能不是 C++,任何语言......我会尝试将它重写为 C++)请分享。

求值的意思是给出表达式的值。 (2+2)*3 是 12

对不起,我忘了我在说堆栈解决方案,因为我知道树解决方案,但这次不合适:(。

【问题讨论】:

  • 不清楚你想做什么。您能否进一步解释一下“评估 infox 表达式”是什么意思?

标签: c++ notation infix-notation


【解决方案1】:

你是怎么得到这个表达式的?如果你得到它就像(3 + 4) - (1 * 2) + 1 =

                  +  
            /          \
           -            1
     /          \   
    +            *          
 /     \      /    \
3      4    1       2

http://cboard.cprogramming.com/cplusplus-programming/32682-inserting-infix-into-binary-tree.html

Left Root Right那样对树进行树横切,所以它会是这样的:3 + 4 结果 - 1 * 2 结果 + 1 的结果。

如果你得到像34+12*-1+ 这样的表达式,你可以像做一个堆栈一样模拟汇编,如果你得到一个运算符,弹出堆栈中的最后两个元素并应用运算符:将 3 放入堆栈,将 4 放入堆栈,得到操作。 + 所以弹出最后两个元素并使用运算符。现在你只有 7 个筹码。现在阅读直到得到一个运算符,所以在堆栈中你将在 op 之后有 7 1 2。 * 在堆栈中,你在 op 之后得到 7 2。 - 你只得到 5 in stack add 1 in stack: Stack 5 1,使用最后一个运算符 + 得到最终结果 6。

好的,代码如下:

#include <STACK>

int GetResult( char * rpn ) 
{
    std::stack<int> myStack;

    int nr1, nr2; int length = strlen(rpn);

    for (int i = 0; i < length; i++)
    {
        if (isdigit(rpn[i]))
        {
            myStack.push(rpn[i] - '0');
        }
        else
        {
            switch(rpn[i])
            {
                case '+':
                    nr1 = myStack.top();
                    myStack.pop();
                    nr2 = myStack.top();
                    myStack.pop();
                    myStack.push(nr2 + nr1);
                    break;

                case '-':
                    nr1 = myStack.top();
                    myStack.pop();
                    nr2 = myStack.top();
                    myStack.pop();
                    myStack.push(nr2 - nr1);
                    break;

                case '*':
                    nr1 = myStack.top();
                    myStack.pop();
                    nr2 = myStack.top();
                    myStack.pop();
                    myStack.push(nr2 * nr1);
                    break;

                case '/':
                    nr1 = myStack.top();
                    myStack.pop();
                    nr2 = myStack.top();
                    myStack.pop();
                    myStack.push(nr2 / nr1);
                    break;
                default:
                    break;
            }
        }
    }

    return myStack.top();
}

int main(int argc, char* argv[])
{
    char *rpn = "34+12*-1+";

    int rez = GetResult(rpn);

    printf("%i", rez);

    return 0;
}

【讨论】:

  • 对不起,我忘记了我正在谈论堆栈解决方案。我知道树的解决方案。
  • @RobertKilar 我不明白。请改写!
  • 我知道我知道树遍历解决方案(我已经做过),但我需要一个堆栈(我们用于 RPN 的一种 - 反向波兰符号)。
  • 那么你想让我发布堆栈解决方案吗?因为我已经解释过了?
  • 如果可能,请发布:)。对不起,我正在阅读我从你们所有人那里得到的所有建议和链接。这会有很大帮助。现在我找到了java解决方案,但它存在一些问题,所以我试图理解它并纠正它。
【解决方案2】:

到目前为止,最简单的方法是使用Dijkstra's Shunting-yard algorithm 将中缀表达式转换为后缀表示法,然后计算结果,这很简单。互联网上到处都有这样的代码示例(看看Rosetta codeLiteratePrograms)。


或者,如果您想学习,并且想进入解析的神奇世界和一点编译器理论,请写信recursive descent parser。很好玩。


哦,如果你想要更健壮的东西,你可以看看 Pratt 解析,它很棒。 Here 是一篇很棒的文章。

【讨论】:

    猜你喜欢
    • 2015-06-08
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 2013-04-03
    • 1970-01-01
    • 2011-12-05
    • 1970-01-01
    相关资源
    最近更新 更多