1. 程式人生 > >逆波蘭表示式演算法

逆波蘭表示式演算法

       逆波蘭表示式又叫做字尾表示式

       在通常的表示式中,二元運算子總是置於與之相關的兩個運算物件之間,這種表示法也稱為中綴表示。波蘭邏輯學家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中的值就是逆波蘭表示式的值了。