1 #include<bits/stdc++.h> 2 using namespace std; 3 int sta[101]; 4 char s[256]; 5 int comp(char s[256]) 6 { 7 int i=0,top=0,x; 8 while(i<=strlen(s)-2) 9 { 10 switch(s[i]) 11 { 12 case'+':sta[--top]+=sta[top+1];break; 13 case'-':sta[--top]-=sta[top+1];break; 14 case'*':sta[--top]*=sta[top+1];break; 15 case'/':sta[--top]/=sta[top+1];break; 16 default: x=0; 17 while(s[i]!=' ')x=x*10+s[i++]-'0'; 18 sta[++top]=x; 19 break; 20 } 21 i++; 22 } 23 return sta[top]; 24 } 25 int main() 26 { 27 gets(s); 28 cout<<comp(s); 29 return 0; 30 }
1 后缀表达式的求值
将中缀表达式转换成等价的后缀表达式后,求值时,不需要再考虑运算符的优先级,只需从左到右扫描一遍后缀表达式即可。具体求值步骤为:从左到右扫描后缀表
达式,遇到运算符就把表达式中该运算符前面两个操作数取出并运算,然后把结果带回后缀表达式;继续扫描直到后缀表达式最后一个表达式。
例如,后缀表达式(abc*+def*/-)
的求值
2
后缀表达式的求值的算法
设置一个栈,开始时,栈为空,然后从左到右扫描后缀表达式,若遇操作数,则进栈;若遇运算符,则从栈中退出两个元素,先退出的放到运算符的右边,后退出的
放到运算符左边,运算后的结果再进栈,直到后缀表达式扫描完毕。此时,栈中仅有一个元素,即为运算的结果。
例,求后缀表达式:1 2 + 8 2 - 7 4 - / *
的值,
栈的变化情如下:
步骤 |
栈中元素 |
说明 |
1 |
1 |
1 进栈 |
2 |
12 |
2 进栈 |
3 |
|
遇+ 号退栈2 和1 |
4 |
3 |
1+2=3 的结果3 进栈 |
5 |
38 |
8 进栈 |
6 |
382 |
2 进栈 |
7 |
3 |
遇- 号退栈2 和8 |
8 |
36 |
8-2=6 的结果6 进栈 |
9 |
367 |
7 进栈 |
10 |
3674 |
4 进栈 |
11 |
36 |
遇- 号退栈4 和7 |
12 |
36 |
7-4=3 的结果3 进栈 |
13 |
3 |
遇/ 号退栈3 和6 |
14 |
32 |
6/3=2 的结果2 进栈 |
15 |
|
遇* 号退栈2 和3 |
16 |
6 |
3*2=6 进栈 |
17 |
6 |
扫描完毕,运算结束 |
从上可知,最后求得的后缀表达式之值为6
,与用中缀表达式求得的结果一致,但后缀式求值要简单得多。
五、中缀表达式变成等价的后缀表达式的算法
将中缀表达式变成等价的后缀表达式,表达式中操作数次序不变,运算符次序发生变化,同时去掉了圆括号。转换规则是:设立一个栈,存放运算符,首先栈为空,
编译程序从左到右扫描中缀表达式,若遇到操作数,直接输出,并输出一个空格作为两个操作数的分隔符;若遇到运算符,则必须与栈顶比较,运算符级别比栈顶级
别高则进栈,否则退出栈顶元素并输出,然后输出一个空格作分隔符;若遇到左括号,进栈;若遇到右括号,则一直退栈输出,直到退到左括号止。当栈变成空时,
输出的结果即为后缀表达式。将中缀表达式(1+2)*((8-2)/(7-4))
变成等价的后缀表达式。
现在用栈来实现该运算,栈的变化及输出结果如下:
步骤 |
栈中元素 |
输出结果 |
说明 |
1 |
( |
|
( 进栈 |
2 |
( |
1 |
输出1 |
3 |
(+ |
1 |
+ 进栈 |
4 |
(+ |
1 2 |
输出2 |
5 |
|
1 2 + |
+ 退栈输出,退栈到( 止 |
6 |
* |
1 2 + |
* 进栈 |
7 |
*( |
1 2 + |
( 进栈 |
8 |
*(( |
1 2 + |
( 进栈 |
9 |
*(( |
1 2 + 8 |
输出8 |
10 |
*((- |
1 2 + 8 |
输出2 |
11 |
*((- |
1 2 + 8 2 |
- 进栈 |
12 |
*( |
1 2 + 8 2 - |
- 退栈输出,退栈到( 止 |
13 |
*(/ |
1 2 + 8 2 - |
/ 进栈 |
14 |
*(/( |
1 2 + 8 2 - |
( 进栈 |
15 |
*(/( |
1 2 + 8 2 - 7 |
输出7 |
16 |
*(/(- |
1 2 + 8 2 - 7 |
- 进栈 |
17 |
*(/(- |
1 2 + 8 2 - 7 4 |
输出4 |
18 |
*(- |
1 2 + 8 2 - 7 4 - |
- 退栈输出,退栈到( 止 |
19 |
* |
1 2 + 8 2 - 7 4 - / |
/ 退栈输出,退栈到( 止 |
20 |
|
1 2 + 8 2 - 7 4 - / * |
* 退栈并输出 |