阿龍學堂-中綴-後綴表達式的計算

1、簡介

在數據結構中,有一種數據結構叫做:Stack,LIFO(Last In First Out),在這個結構中,有個後綴表達式計算,運用該數據結構進行計算。

棧是一種只允許一端操作的線性數據結構,具有LIFO(last in first out)的特點,具有廣泛的應用,如我在遊戲編程模式--命令模式(2)中使用棧的結構來實驗撤銷、重做功能。現在打算用棧結構來實現後綴表達式的計算。

後綴表達式也叫逆波蘭表達式,其求值過程可以用到棧來輔助存儲。

2、後綴表達式

後綴表達式,指的是不包含括號,運算符放在兩個運算對象的後面,所有的計算按運算符出現的順序,嚴格從左向右進行(不再考慮運算符的優先規則)。

例如 5+(2+3)*4 轉換爲後綴表達式爲 523+4*+

3、後綴表達式的計算

規則:從左向右掃描,遇到數字壓棧,遇到操作符,彈出棧頂的兩個元素,先彈出的元素在右邊,後彈出來的在左邊,進行計算後,將結果壓棧,再往後掃描,直到掃描結束,輸出棧頂元素,即爲最終結果。
523+4*+爲例
5壓棧 2壓棧 3壓棧 遇到+號,彈出3 2,計算2+3,將5壓棧,此時棧爲5 5,將4壓棧,遇到*號,彈出4 5,計算5*4,將20壓棧 此時棧爲5 20 ,遇到+號,計算5+20,將25壓棧,掃描結束,輸出25。
以上就是計算過程。下面用C++編寫代碼,爲了方便標記算式的結束,在末尾我們加上#,用來標識算式結束,這裏我們只進行四則運算

#include <iostream>
#include <stack>
#include "string"
using namespace std;

int main()
{
    stack<int> a;
    string temp;
    cin >> temp;
    int i = 0;
    while (true)
    {
        if (temp[i]=='#') cout << a.top(); break;
        if (temp[i]<='9'&&temp[i]>='0') a.push(temp[i]-48);
        else
        {
            int x, y;
            y = a.top(); a.pop();
            x = a.top(); a.pop();
            switch (temp[i])
            {
            case '+':a.push(x + y); break;
            case '-':a.push(x - y); break;
            case '*':a.push(x * y); break;
            case '/':a.push(x / y); break;
            default:break;
            }
        }
        ++i;        
    }
    cin >> temp;
    return 0;
}

4、中綴表達式轉後綴表達式

4.1、規則

中綴表達式a + b*c + (d * e + f) * g,其轉換成後綴表達式則爲a b c * + d e * f  + g * +。

轉換過程需要用到棧,具體過程如下:

1)如果遇到操作數,我們就直接將其輸出。

2)如果遇到操作符,則我們將其放入到棧中,遇到左括號時我們也將其放入棧中。

3)如果遇到一個右括號,則將棧元素彈出,將彈出的操作符輸出直到遇到左括號爲止。注意,左括號只彈出並不輸出。

4)如果遇到任何其他的操作符,如(“+”, “*”,“(”)等,從棧中彈出元素直到遇到發現更低優先級的元素(或者棧爲空)爲止。彈出完這些元素後,纔將遇到的操作符壓入到棧中。有一點需要注意,只有在遇到" ) "的情況下我們才彈出" ( ",其他情況我們都不會彈出" ( "。

5)如果我們讀到了輸入的末尾,則將棧中所有元素依次彈出。

4.2、實例

規則很多,還是用實例比較容易說清楚整個過程。以上面的轉換爲例,輸入爲a + b * c + (d * e + f)*g,處理過程如下:

1)首先讀到a,直接輸出。

2)讀到“+”,將其放入到棧中。

3)讀到b,直接輸出。

4)讀到“*”,因爲棧頂元素"+"優先級比" * " 低,所以將" * "直接壓入棧中。

5)讀到c,直接輸出

6)讀到" + ",因爲棧頂元素" * "的優先級比它高,所以彈出" * "並輸出, 同理,棧中下一個元素" + "優先級與讀到的操作符" + "一樣,所以也要彈出並輸出。然後再將讀到的" + "壓入棧中。

7)下一個讀到的爲"(",它優先級最高,所以直接放入到棧中。

8)讀到d,將其直接輸出。

9)讀到" * ",由於只有遇到" ) "的時候左括號"("纔會彈出,所以" * "直接壓入棧中。

10)讀到e,直接輸出。

11)讀到" + ",彈出" * "並輸出,然後將"+"壓入棧中。

12)讀到f,直接輸出。

13)接下來讀到“)”,則直接將棧中元素彈出並輸出直到遇到"("爲止。這裏右括號前只有一個操作符"+"被彈出並輸出。

14)讀到" * ",壓入棧中。讀到g,直接輸出。

15)此時輸入數據已經讀到末尾,棧中還有兩個操作符“*”和" + ",直接彈出並輸出。至此整個轉換過程完成。程序實現代碼後續再補充了。

4.3、轉換的另一種方法

1)先按照運算符的優先級對中綴表達式加括號,變成( ( a+(b*c) ) + ( ((d*e)+f) *g ) )

2)將運算符移到括號的後面,變成((a(bc)*)+(((de)*f)+g)*)+

3)去掉括號,得到abc*+de*f+g*+

 

 

具體細節關注微信公衆號   【阿龍學堂】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章