中缀表达评估

时间:2012-08-25 12:57:49

标签: c++ notation infix-notation

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

评估意味着给出表达的价值。 (2 + 2)* 3是12

对不起,我忘记了我正在谈论堆栈解决方案,因为我知道树解决方案而且这次不合适:(。

2 个答案:

答案 0 :(得分:3)

你是如何得到这个表达的?如果你得到它(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+这样的表达式,你可以像堆栈那样模拟汇编,如果你到达运算符,则弹出堆栈中的最后2个元素并应用运算符:将3放入堆栈,将4放入堆叠,得到操作。 +所以弹出最后2个元素并使用运算符。现在你只有7个筹码。现在阅读,直到得到一个操作员,所以在堆栈中你将在操作后得到7 1 2。 *在筹码中你得到了7 2。 - 堆栈中只有5个加1堆栈:堆栈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;
}

答案 1 :(得分:1)

到目前为止,最简单的方法是使用Dijkstra's Shunting-yard algorithm将中缀表达式转换为后缀表示法,并调整结果,就像琐碎一样。互联网上有代码示例(请查看Rosetta codeLiteratePrograms)。


或者,如果您想学习,并且想要进入解析的神奇世界和一些编译器理论,请写一个recursive descent parser。这很有趣。


哦,如果你想要更强大的东西,你可以看一下Pratt解析,这太棒了。 Here是一篇很棒的文章。