什么是中綴表達式,什么是后綴表達式
我們一般看見的多項式計算都是中綴表達式構成的:1+2*3+4/3
類似這種,為什么說是中綴呢?因為它的計算符號都是在兩個數中間的。
那么自然而然的明白了后綴表達式是一種計算符號在兩個數后面的。
如123*+43/+
中綴表達式和后綴表達式有什么關系?
其實仔細你就會發現,上面給出的式子其實都是一樣的,只是計算的順序在后綴表達式中你看不懂而已。
因為我們習慣去看中綴表達式的計算。
其實他們之間是可以互相轉換的。他們也可以表達同一個意思,同一個計算式子。
為什么會提出后綴表達式
這里馬上就會有問題了,為什么好好的不用中綴表達式,而提出那么一個難看的后綴表達式。
首先對於我們人來說,計算的時候看到乘法和除法自然而然的就會去先計算,而對於計算機這么笨的東西來說,它不知道。
對於中綴表達式來說,計算機不能預料到后面是否會出現高階的計算符號,是否要先進行計算,所以在計算的次序上面很有可能出錯。
所以就有了后綴表達式,計算機在計算后綴表達式的時候不用擔心計算的次序。那么問題就來了,如何計算一個后綴表達式的值呢?
別急,我們先來看看如何把一個中綴表達式轉換成一個后綴表達式。
中綴表達式轉換成后綴表達式
這里我們提前約定一下,我們的式子包含加減乘除和小括號,所有的數據我們暫時用個位數來表示,不包含次方開方和中括號。當然也不是可以,我們這邊將問題盡量簡單化。
1. 從左向右掃遍歷表達式:
2. If 當前遍歷到的字符 ch 是操作數,則打印
3. Else If 當前遍歷的ch是 ‘(‘, 入棧
4. Else If 當前遍歷的ch是 ‘)’, 不斷彈出棧頂元素,直到棧為空或彈出’(‘
5. Else,
…….5.1 If 上一個操作符的優先級比當前操作符ch的優先級小,或棧是空的就入棧。
……. 5.2 Else, 不斷彈出棧頂的操作符,並打印,直到棧為空或當前的操作符ch的優先級大於棧頂的操作符。將當前操作符入棧。
6. 重復2-6步,直到遍歷完成
7. 彈出並打印棧中的剩余的操作符
代碼描述
#include<cstdio> #include<iostream> #include<cstdlib> #include<string> #include<string.h> #include<stack> using namespace std; int getRank(char sign) { switch(sign) { case '+': case '-': return 1; case '*': case '/': return 2; } return -1; } int main() { int i=0; stack<char> expStack; string expression; cin>>expression; for(i=0; i<expression.length(); i++) { if(expression[i]>='0' && expression[i]<='9') { cout<<expression[i]; } else if(expression[i] == '(') { expStack.push(expression[i]); } else if(expression[i] == ')') { char top = expStack.top(); expStack.pop(); while(!expStack.empty() && top != '(') { cout<<top; top = expStack.top(); expStack.pop(); } } else { int now = getRank(expression[i]); if(expStack.empty() || now > getRank(expStack.top())) { expStack.push(expression[i]); } else { while(!expStack.empty() && now <= getRank(expStack.top())) { cout<<expStack.top(); expStack.pop(); } expStack.push(expression[i]); } } } while(!expStack.empty()) { cout<<expStack.top(); expStack.pop(); } return 0; }
后綴表達式的計算
我們現在已經能得到后綴表達式了,那么如何利用它計算。
其實很簡單,首先我們觀察到后綴表達式中已經沒有任何括號了,所以對於我們來說計算順序就很容易了。
從左往右讀取,數字入棧,如果遇到計算符號(比如遇到一個加號),出棧兩個數然后計算(比如兩個數相加),然后將結果入棧。
最后在棧中的數據就為計算的結果。
思考
棧對於帶有括號的計算式,四則運算等比較好用,利用棧的特性能保存一些計算等級低的,讓等級高的先進行計算。
之后遇到這樣的問題可以首先考慮使用棧。
