中缀表达式求值的方法—栈

对于像是1+2的中缀表达式,我们可以轻松地运用代码来算出结果。

但是对于1+(2^2)/3*4这样的表达式,事情就变得有些复杂了...

对于上述的表达式,我们可以运用栈的相关知识来解决—建立两个栈,栈1放数字,栈2放运算符;遇到数字时入栈1;遇到运算符时,若栈2为空,则运算符直接入栈;若栈2非空,则将当前运算符与栈2中栈顶的运算符进行比较优先级,根据优先级进行下一步操作。代码如下:

  1 #include <iostream>
  2 #include <string.h>
  3 #include <math.h>
  4 #include <stack>
  5 #define Maxsize 50
  6 using namespace std;
  7 stack<int> S1;//栈1保存数
  8 stack<char> S2;//栈2保存运算符
  9 void Calculate(char a)//用以计算的函数
 10 {
 11   int b,c,d=0;//b和c为表达式中的数,d为计算结果
 12   if(a=='+'){//加法
 13     b=S1.top();
 14     S1.pop();
 15     c=S1.top();
 16     S1.pop();
 17     d=c+b;
 18     S1.push(d);
 19   }
 20   if(a=='-'){//减法
 21     b=S1.top();
 22     S1.pop();
 23     c=S1.top();
 24     S1.pop();
 25     d=c-b;
 26     S1.push(d);
 27   }
 28   if(a=='*'){//乘法
 29     b=S1.top();
 30     S1.pop();
 31     c=S1.top();
 32     S1.pop();
 33     d=c*b;
 34     S1.push(d);
 35   }
 36   if(a=='/'){//除法
 37     b=S1.top();
 38     S1.pop();
 39     c=S1.top();
 40     S1.pop();
 41     d=c/b;
 42     S1.push(d);
 43   }
 44   if(a=='^'){//指数运算
 45     b=S1.top();
 46     S1.pop();
 47     c=S1.top();
 48     S1.pop();
 49     d=pow(c,b);
 50     S1.push(d);
 51   }
 52 }
 53 int main()
 54 {
 55   char a[50],e;//数组a存放表达式
 56   int num;//辅助变量
 57   int sum=0;//计算结果
 58   cin.getline(a,50);
 59   for(int i=0;i<strlen(a);i++){
 60     if(a[i]>='0'&&a[i]<='9'){//处理数字
 61       num=0;
 62       while((a[i]>='0'&&a[i]<='9')){//数字可能大于10,处理到非数字的字符时即跳出循环
 63         num=num*10+(a[i]-'0');
 64         i++;
 65       }
 66       S1.push(num);
 67       //cout<<S1.top()<<endl;
 68       i--;//注意跳出上面的while后i需要减1
 69     }
 70     if(!isdigit(a[i])){//处理运算符
 71       if(S2.empty()){//栈2为空
 72         S2.push(a[i]);
 73         //cout<<S2.top()<<endl;
 74       }
 75       //处理'^'
 76       else if(a[i]=='^'){
 77         if(S2.top()!='^') S2.push(a[i]);
 78         else{
 79           while(!S2.empty()&&S2.top()=='^'){
 80             Calculate(S2.top());
 81             S2.pop();
 82           }
 83           S2.push(a[i]);
 84         }
 85       }
 86       //处理'*'和'/'
 87       else if(a[i]=='*'||a[i]=='/'){
 88         while(!S2.empty()&&S2.top()!='+'&&S2.top()!='-'&&S2.top()!='('){
 89           Calculate(S2.top());
 90           S2.pop();
 91         }
 92         S2.push(a[i]);
 93       }
 94       //处理'+'和'-'
 95       else if(a[i]=='+'||a[i]=='-'){
 96         while(!S2.empty()&&S2.top()!='('){
 97           Calculate(S2.top());
 98           S2.pop();
 99         }
100         S2.push(a[i]);
101       }
102       else if(a[i]=='(') S2.push(a[i]);//处理左括号
103       else if(a[i]==')'){//处理右括号,退栈直到遇到左括号
104         while(!S2.empty()&&S2.top()!='('){
105           Calculate(S2.top());
106           S2.pop();
107         }
108         S2.pop();
109       }
110     }
111   }
112   while(!S2.empty()){//若栈2还有运算符,则继续计算
113     Calculate(S2.top());
114     S2.pop();
115   }
116   cout<<int(S1.top());//输出结果
117   return 0;
118 }

以上是c++实现表达式求值的代码,使用python一行代码就可以解决,python代码如下:

1 print(eval(input().replace('/','//').replace('^','**')))

python使用起来固然简单,但是理解背后的原理才是更重要的。

posted @ 2020-05-20 17:47  peach1  阅读(558)  评论(0编辑  收藏  举报