超級詳解中綴表示式與字尾表示式

2021-10-02 19:45:54 字數 2980 閱讀 4904

首先我們應該知道我們平常所列的式子如2+3*5 這樣的式子就稱為中綴表示式。這個式子的字尾表示式是這樣的 235*+ 。之所以這樣做,是因為字尾表示式更容易讓計算機讀懂,而中綴表示式更符合我們自己的理解。在這裡很多文章和書都會直接告訴你如何進行轉化,相信大家也都看的頭暈目眩。而我認為,想理解如何實現,我們先要完成兩步驟:讀懂字尾表示式、手寫轉化中綴表示式。

首先我們先要讀懂字尾表示式,把自己想象成乙個沒有感情的機器,它想象成為乙個字串,其中的內容有兩種:數字(1,2,3)和運算元(+,-,*,/),我們分別稱之為num 和op。以235*+為例從左到右,找到第乙個op,是*從這個op的前面依次找到兩個數字(5和3),然後執行 num1  op  num2 (即5*3)(注意這裡要注意一下num1和2的順序了,因為減法除法會要求順序)計算出來的結果再放回剛才的位置 。也就是說我們現在的表示式變成了  2(15)+  沒錯吧?我們再按照剛才的方法執行,找到+號,再找前面兩個值(2和15)再做加法,就得到了結果17。當我們發現表示式裡面只有數字了,沒有感情的機械人也就結束了迴圈。是不是很簡單?***列幾個式子,你來計算一下對不對吧

字尾表示式

中綴表示式

結果235*+

2+3*5

178462*-+

8+4-6*2

035+2*71/+4-

2*(3+5)+7/1-419

經過剛才的訓練你應該已經能夠看懂字尾表示式了,相信理解能力比較強的同學也可以自己模仿著拿中綴表示式寫成字尾表示式了。下面我們來看一下,如何手寫轉化吧。大家應該已經注意到計算機通過遍歷中綴表示式,找op,然後從前找兩個數去做運算。當我們自己逆過來自己寫的時候,就應該把num1num2寫著前面,後面緊跟要進行運算的op。比如3*5我們就要寫成35*;2+6我們就要寫成26+;那麼2+3*5我們需要先進行運算的是3*5然後再和2相加,所以我們對於op是+這個運算來說num1是2,num2是3*5的結果所以我們寫的是2(3和5相乘的結果)+  。對吧?然後3和5相乘是什麼呢?35*對吧。所以我們寫出來的字尾表示式就是235*+;再把上面的中綴表示式看一遍,大家能不能寫出字尾表示式了呢?

分析一下我們剛才做num1 op num2這個過程,找乙個最近的op然後把最近的兩個數字拿出來,算結果,再放回去。這不就是棧嗎!!!!!用棧再好不過了啊啊啊啊啊啊!!!我們只需要在字尾表示式中遇到數字就往裡壓,遇到op彈出倆數字,算完了壓進去,然後迴圈往復走到頭不就完了嗎!!!這樣一看大家應該就明白了為什麼我們要辛辛苦苦的轉換成字尾表示式了,這對計算機來說太方便了。

還剩下最後乙個難點,計算機如何把中綴表示式轉化成字尾表示式呢?其實也很簡單我們也需要乙個存放op的棧來做輔助,間接的改變這些運算的順序。我們先看看借用這個棧,轉化遵循的規則(我盡量用自己的話說,書面語書上和其他人的文章中想必很多),如下,一定要乙個字乙個字讀:

掃瞄中op stack

(右邊是棧頂)

已經生成的字尾表示式備註a

空a是num,直接加到表示式後面a++

a是op,棧空,壓棧

a+b+

ab是num,直接加到表示式後面

a+b*

+*ab

是op,*優先順序大於+,壓棧

a+b*c

+*abc

是num,直接加到表示式後面

a+b*c-

-abc*+

【重點!】-<*,故*彈出,-=+故+彈出,然後-進棧

a+b*c-d

-abc*+d

是num,直接加到表示式後面

a+b*c-d\

-/abc*+d

是op,/優先順序大於-,直接將/壓棧

a+b*c-d\e

-/abc*+de

是num,直接加到表示式後面,結束

a+b*c-d\e

空abc*+de\-

棧不是空,依次彈棧到棧空

相信看完這個表,大家應該都明白了吧?補充一下,()括號的問題我沒有說,有括號方法也很簡單,只需要在壓棧時候如果是左括號就壓棧是右括號就不斷彈棧直到碰見左括號就可以了。為了講的更清楚就不提()括號的問題了。原理理解了下面只剩下實現了。

懂得了原理,**實現就很簡單了,這裡由於大家都是學習資料結構,就不使用stl了。可以使用map做op與優先順序的一一對映,使用#include輕鬆實現棧,為了強化基本功,我們手寫乙個鍊錶棧並在此之上實現轉換。特別指出,我們為了著重理解演算法核心,省略了一些如字串處理,map做對映關係等的繁枝末節。約束如下:

對於轉化後的計算,我們就不做重點討論啦,如上文說過的,非常簡單,遇到num壓棧,遇到op連續彈兩次棧,計算後再壓回去,直到只有乙個數,那就是結果。實現比較簡單,我們就不做了。附上源**!:

#include #include #include #includeusing namespace std;

void change(char a);

int cauculate(char a);

int main()

void change(char a)

case '+':

stk.push('+');

break;

}case '-':

stk.push('-');

break;

}case '*':

if(stk.top()=='+'||stk.top()=='-')

stk.push('*');

else

stk.push('*');

}break;

}case '/':

if(stk.top()=='+'||stk.top()=='-')

stk.push('/');

else

stk.push('/');

}break;}}

}while(!stk.empty())

res[index]='\0';

strcpy(a,res);

}int cauculate(char a)

else}}

return stk.top();

}

中綴表示式 字尾表示式

中綴表示式就是 a b 這樣的,運算子在兩個數的中間 字尾表示式就是 a b 這樣的,運算子在兩個數後面 再細分一下 中綴表示式 字尾表示式 a b c a b c a b c a b c a b c a b c a b c a b c a b c d e a c a b c d e a c emm...

中綴表示式 字尾表示式

數學表示式稱為中綴表示式,符合人的思考習慣 1 2 3運算子放在數字後面,符合計算機運算 123 遍歷中綴表示式中的數字和符號 左括號 入棧 運算符號 需要與棧頂符號進行優先順序比較 遍歷結束 將棧中所有符號彈出並輸出。例 中綴表示式 1 2 5 3 4 2 1 1 數字1直接輸出 結果 1 棧 空...

中綴表示式 字尾表示式

表示式 x a b c d e 的字尾表示形式可以為 c a xab cde b xa bc de c xabcd e d xabcde 表示式前字尾表達形式 乙個中綴式到其他式子的轉換方法 這裡我給出乙個中綴表示式 a b c d e 第一步 按照運算子的優先順序對所有的運算單位加括號 式子變成拉...