1. 程式人生 > >逆波蘭表示式,走一波

逆波蘭表示式,走一波

逆波蘭表示式又叫字尾表示式,中學時候學的那種表示式叫中綴表示式。

例如,5×(6+3)÷3-1      ,  3×(4÷(2+1)×2)-3

例子中的這兩個式子,就是中綴表示式。下面這兩個就是字尾表示式:

563+×3÷1-      ,    3421+÷2××3-

中綴表示式變字尾表示式方法:

見到數字直接輸出,見到符號按一定規則入棧出棧。

規則就是,用當前的符號與棧頂的符號比較優先順序,如果當前符號優先順序小於棧頂符號的優先順序,則把棧裡面的符號都彈出來。括號的操作除外,括號是左括號優先順序最高,不管跟啥比,都是入棧;右括號是優先順序最低,跟啥比都是彈出棧內符號,但只彈到跟它匹配的最近的那個左括號。

這裡就涉及到一個符號優先順序的問題。看下圖吧,從上往下的符號是優先順序從高到低。


這樣就可以開始說怎麼互相轉換了。上面的兩個例子式子都說一說:

                       5×(6+3)÷3-1

先看到的是5,直接輸出,現在的字尾表示式為:“5”。下一個,“×”,壓入棧中。下一個,“(”,優先順序超級高,處在金字塔頂端的符號,也壓入棧中。下一個,“6”,數字,直接輸出,現在的字尾表示式為:“56”。目前狀況看下圖吧。

下一個, “+” ,當棧頂是 “(” 的時候,當前的符號優先順序是一定小於 “(” 的,但不能還按照原來的規則,把棧內符號彈出。 “(” 的彈出條件是等到與之匹配的最近的

“)” 。只有等到了 “)” , “(” 才彈出。當然了, “(” 和 “)” 中間一定還會有別的運算子,彈的時候一起都彈出來。而且當遇到 “)” 的時候,不是全棧都彈出來,而是彈到 “(” 停止。那麼,再說回來,當前符號是 “+” ,由於 “(” 只等到 “)” 才彈出,所以把 “+” 壓入棧中。下一個, “3” ,直接輸出。目前的狀況看下圖。


下一個, “)” ,這個優先順序極低,所以彈出棧中元素,但這個也不能按常規的規則操作。遇到 “)” 了,不應把全棧都彈出來,而是隻彈到 “(” ,因此,現在棧裡面從棧頂一直往下彈,彈到 “(” 為止。目前的狀況看下圖。


下一個, “÷” ,跟棧頂符號 “×” 比優先順序為同級,則將棧中元素都彈出來,即 “×” 彈出,將 “÷” 壓入棧中。因為轉換規則是,當前符號與棧頂符號比較,優先順序大於棧頂符號,才不彈出直接壓入;否則就要先彈出,即清空棧再壓入。

簡單說就是,當前符號優先順序大於棧頂符號優先順序時,不彈出直接壓入;小於等於時,彈出再壓入。目前的狀況看下圖。


下一個, “3” ,直接輸出,此時輸出為:563+×3。下一個, “-” ,這個符號跟棧頂符號比較,優先順序低於棧頂符號,so,彈出棧中元素,把 “-” 壓入棧中。目前的狀況看下圖。


下一個, “1” ,直接輸出,此時輸出為:563+×3÷1。原中值表示式沒有元素了,最後一步操作將棧內還沒彈出的符號都彈出。【在計算機中,其實是自動向中綴表示式末尾填充一個 “#” ,由於 “#” 優先順序最低,這樣在搜尋到 “#” 時,就會清空棧。但 “#” 不參與表示式的計算,就是輸出時,沒有 “#” 。這和陣列最後一位是結束符是同樣的道理。彈出時符號寫在輸出中的順序是,按從棧底到棧頂這個順序在輸出表達式中從左到右列出。最後的輸出就是:563+×3÷1-

下面貼一張百度百科的演算法說明


---------------------------------------------------------------------------------------先寫這些,等有空兒再繼續----20170223 18:47-----