1. 程式人生 > >字首、中綴、字尾表示式轉換詳解

字首、中綴、字尾表示式轉換詳解


字首、中綴、字尾表示式轉換詳解

昨天參加了ebay實習生筆試題,其中一道題目給定了字首表示式,讓我們求轉換成中綴表示式時輔助棧的做多情況下容乃幾個元素以及中綴表示式的值。當時沒有做出來,會後後網上查了些資料,發現很少有文章將字首、中綴和字尾表示式之間的轉化覆蓋了,所以寫下這篇文章希望能夠將字首、中綴和字尾表示式之間的轉化講解清楚。

一般而言,我們最常遇到的是將中綴表示式轉化為字尾表示式,既然這樣,首先就來看看中綴表示式轉化為字尾表示式的方法。

中綴表示式轉字尾表示式:

假定有中綴表示式1 + (( 2 + 3)* 4 ) – 5,請將它轉化為字尾表示式。

方法一:利用表示式樹

首先將中綴表示式轉換為表示式樹,然後後序遍歷表示式樹,所得結果就是字尾表示式。

將中綴表示式轉化為表示式樹方法:表示式樹的樹葉是運算元,而其他的節點為操作符,根節點為優先順序最低且靠右的操作符(如上述表示式優先順序最低的是- 和+,但 + 更靠右,所以根為+),圓括號不包括。如上述中綴表示式轉換後的表示式樹如下:


經過後序遍歷表示式樹後得到的字尾表示式為:12 3 + 4 * + 5 –

方法二:利用輔助棧

從左到右遍歷中綴表示式的每個運算元和操作符。當讀到運算元時,立即把它輸出,即成為字尾表示式的一部分;若讀到操作符,判斷該符號與棧頂符號的優先順序,若該符號優先順序高於棧頂元素,則將該操作符入棧,否則就一次把棧中運算子彈出並加到字尾表示式尾端,直到遇到優先順序低於該操作符的棧元素,然後把該操作符壓入棧中。如果遇到”(”,直接壓入棧中,如果遇到一個”)”,那麼就將棧元素彈出並加到字尾表示式尾端,但左右括號並不輸出。最後,如果讀到中綴表示式的尾端,將棧元素依次完全彈出並加到字尾表示式尾端。

仍然以上面的表示式為例,其轉換過程如下:


利用輔助棧字尾表示式與用表示式樹的結果一樣,都為:1 2 3 + 4 * + 5 –

字尾表示式轉換為中綴表示式

假定有後綴表示式1 2 3 + 4 * +5 – ,請將它轉化為字首表示式。

方法一:利用表示式樹

從左到右掃面字尾表示式,一次一個符號讀入表示式。如果符號是運算元,那麼就建立一個單節點樹並將它推入棧中。如果符號是操作符,那麼就從棧中彈出兩個樹T1和T2(T1先彈出)並形成一顆新的樹,該樹的根就是操作符,它的左、右兒子分別是T2和T1。然後將指向這棵新樹的指標壓入棧中。


前三個符號是運算元,因此建立三顆單節點樹並將指向它們的指標壓入棧中。


“+”被讀入,因此指向最後兩顆樹的指標被彈出,形成一顆新樹,並將指向新樹的指標壓入棧中。以下的流程圖以相同原理執行。




最後再中序遍歷所得的表示式樹即得到我們所需的中綴表示式:1+((2+3)*4)-5

中綴表示式轉換為字首表示式

假定有中綴表示式1 + (( 2 + 3)* 4 ) – 5,請將它轉化為字首表示式。

方法一:利用表示式樹

先將表示式用表示式樹來表示,然後在前序遍歷表示式樹即得到我們所需的字首表大式。表示式樹前面已經介紹過,這裡不再累贅。

此處,經過前序遍歷所得字首表示式為:- + 1 * + 2 3 4 5

方法二:利用輔助棧

首先構造一個運算子棧,然後從右至左掃描中綴表示式。如果是運算元,則直接輸出,作為字首表示式的一個直接轉換表示式Temp(最後,字首表示式由該表示式翻轉得到);如果是運算子,則比較優先順序:若該運算子優先順序大於等於棧頂元素,則將該運算子入棧,否則棧內元素出棧並加到Temp表示式尾端,直到該運算子大於等於棧頂元素的優先順序時,再將該運算子壓入棧中。遇到右括號直接壓入棧中,如果遇到一個左括號,那麼就將棧元素彈出並加到Temp表示式尾端,但左右括號並不輸出。最後,若運算子棧中還有元素,則將元素一次彈出並加到Temp表示式尾端,最後一步是將Temp表示式翻轉。

         其過程如下圖所示:


從右到左開始掃描,5為數字放入Temp中,-為操作符入棧。


遇到左括號,元素彈出直到遇到右括號為止。



所得字首表示式為:- + 1 * + 2 3 4 5

字首表示式轉換為中綴表示式:

假定有字首表示式 - + 1 * + 23 4 5,請將它轉化為中綴表示式。

方法一:輔助棧

首先建立一個數字棧。從右到左掃描字首表示式,如果遇到運算元,則入棧。如果遇到操作符,則將棧頂元素彈出(後掃面的數字位於表示式前面),並和操作符結合寫成表示式,作為中綴表示式。如果遇到的操作符優先順序大於已存在表示式的最後執行操作符的優先順序,則將已存在的表示式加上()。

如下是字首表示式轉為中綴表示式的示意圖:

掃描到運算元直接入棧。


掃描到操作符,將兩個棧頂元素彈出,並和操作符結合寫成表示式。




表示式不是(2+3)*4,因為1比2、3、4後掃描到。


表達是不是5-(1+(2+3)*4),因為5是最早掃面到的數字。

所以中綴表示式為5-(1+(2+3)*4)。


==轉載請註明出處,謝謝!http://blog.csdn.net/walkerkalr/article/details/22798365