Infix表达式评估

Infix expression evaluation

本文关键字:评估 表达式 Infix      更新时间:2023-10-16

我想在C++中计算(而不是转换)中缀表达式。如果你有算法,甚至是这样的算法的实现(用任何语言……我会尝试把它重写成C++),请分享。

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

更新

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

你是如何得到这个表达式的?如果你得到它像(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,得到op.+,则弹出最后两个元件并使用该运算符。现在你只剩下7个了。现在读取,直到得到一个运算符,所以在堆栈中op.*在堆栈中,op.-在堆栈中只得到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;
}

到目前为止,最简单的方法是使用Dijkstra的Shutting yard算法将中缀表达式转换为后缀表示法,并计算结果,这就像是微不足道的。互联网上到处都有这样的代码示例(看看罗塞塔代码或LiteratePrograms)。


或者,如果你想学习,想进入解析和编译器理论的神奇世界,可以写一个递归下降解析器。这很有趣。


哦,如果你想要更健壮的东西,你可以看看Pratt解析,这太棒了。这是一篇关于它的好文章。