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 - / * |
* 退棧並輸出 |