逆波蘭表示式演算法
逆波蘭表示式又叫做字尾表示式。
在通常的表示式中,二元運算子總是置於與之相關的兩個運算物件之間,這種表示法也稱為中綴表示。波蘭邏輯學家J.Lukasiewicz於1929年提出了另一種表示表示式的方法,按此方法,每一運算子都置於其運算物件之後,故稱為字尾表示式。
逆波蘭是一種十分有用的表示式,它將複雜表示式轉換為可以依靠簡單的操作得到計算結果的表示式。例如(a+b)*(c+d)轉換為ab+cd+*。
它的優勢在於只用兩種簡單操作,入棧和出棧就可以搞定任何普通表示式的運算。1.如何將一箇中序表示式轉換成逆波蘭表示式:
首先定義兩個棧:S1和S2。S1中儲存最終形成的逆波蘭表示式,S2將用於暫時存放運算子(在最終形成逆波蘭表示式的時候,清空該棧)。
下面詳細說明如何形成一個逆波蘭表示式:
首先要明確各運算子之間的優先順序關係,然後從左到右遍歷一個給定的中序表示式:
(1)如果遇到的是數字,將數字壓入S1中;
(2)如果遇到的是左括號,將左括號壓入S2中;
(3)如果遇到的是右括號,將S2中的運算子一直出棧壓入S1中,直到遇到左括號,但是該左括號出S2卻不入S1;
(4)如果遇到的是運算子,按照如下規則操作:
(1)如果S2為空,將運算子壓入S2中;
(2)如果S2不為空,當前遍歷到的運算子優先順序不小於S2棧頂運算子,將當前遍歷到的運算子壓入S2;
(3)如果S2不為空,當前遍歷到的運算子優先順序小於S2棧頂運算子,將棧頂運算子一直出棧壓入S1中,直到棧為空或遇到一個運算子優先 級小於當前遍歷到的運算子,此時將當前遍歷到的運算子壓入S2;
(5)直到遍歷完整個中序表示式後,若S2中仍然存在運算子,將這些運算子依次出棧壓入S1,直到S2為空;
按照上面5條規則反覆操作,最終會在S1中形成需求的逆波蘭表示式。
2.利用逆波蘭表示式求值
首先定義一個棧:S3,在該棧中存放最終表示式的值。從左到右遍歷S1,然後按照如下規則操作S3:
(1)如果遇到的是數字,將數字壓入S3中;
(2)如果遇到單目運算子(運算物件只有一個的運算子,如:或(|)、與(&)等),取S3棧頂一個元素進行單目運算,將結果再次壓入S3中;
(3)如果遇到雙目運算子(運算物件有兩個的運算子,如:加(+)、賦值(=)等),取S3棧頂兩個元素(先出棧的在左,後出棧的在右)進行
雙目運算,將結果再次壓入S3中;
按照上面3條規則遍歷完S1,那麼最後S3中的值就是逆波蘭表示式的值了。