字首 中綴 字尾表示式計算和轉化演算法詳解

2021-10-08 09:04:33 字數 3602 閱讀 4407

字首、中綴、字尾表示式是對表示式的不同記法,其區別在於運算子相對於數字的位置不同,字首表示式的運算子位於運算元之前,中綴和字尾同理

如:中綴表示式:1 + (2 + 3) × 4 - 5

字首表示式:- + 1 × + 2 3 4 5

字尾表示式:1 2 3 + 4 × + 5 -

中綴表示式是人們最常用的算術表示方法,人腦很容易理解,但對計算機來說很複雜,因為要判斷計算的優先順序太過繁瑣。對計算機來說,計算字首或字尾表示式的值非常簡單

1+(2+3)*4-5為例

先根據計算的優先順序加上括號。

然後將運算子從優先順序最低的括號移到該括號外,並刪去括號

((1+((2+3)×4))-5)

-(1+((2+3)×4))5

-+1((2+3)×4)5

-+1×(2+3)45

-+1×+2345

或 先根據計算的優先順序加上括號,然後將每個運算子移到其所在最內部的括號前面,最後一次性刪除括號

((1+((2+3)×4))-5)

-(+(1×(+(23)4))5)

-+1×+2345

同理,也是先加上括號,然後將運算子移動到其所在最內部的括號後面,刪除括號

((1+((2+3)×4))-5)

((1((23)+4)×)+5)-

123+4×+5-

從右至左掃瞄表示式

遇到數字時,將數字壓棧,遇到運算子時,彈出棧頂的兩個數,計算並將結果入棧

重複2直到表示式最左端,最後運算得出的值即為表示式的結果 例:

計算字首表示式的值:- + 1 × + 2 3 4 5

從右至左掃瞄,將5,4,3,2壓入堆疊;

遇到+運算子,彈出2和3(2為棧頂元素,3為次頂元素),計算2+3的值,得到5,將5壓入棧;

遇到×運算子,彈出5和4,計算5×4的值,得到20,將20壓入棧;

遇到1,將1壓入棧;

遇到+運算子,彈出1和20,計算1+20的值,得到21,將21壓入棧;

遇到-運算子,彈出21和5,計算21-5的值,得到16為最終結果

與字首表示式類似,只是順序是從左至右:

從左至右掃瞄表示式

遇到數字時,將數字壓棧,遇到運算子時,彈出棧頂的兩個數,計算並將結果入棧

重複2直到表示式最右端,最後運算得出的值即為表示式的結果

示例:計算字尾表示式的值:1 2 3 + 4 × + 5 -

從左至右掃瞄,將1,2,3壓入棧;

遇到+運算子,3和2彈出,計算2+3的值,得到5,將5壓入棧;

遇到4,將4壓入棧

遇到×運算子,彈出4和5,計算5×4的值,得到20,將20壓入棧;

遇到+運算子,彈出20和1,計算1+20的值,得到21,將21壓入棧;

遇到5,將5壓入棧;

遇到-運算子,彈出5和21,計算21-5的值,得到16為最終結果

轉換演算法

(1) 首先構造乙個運算子棧(也可放置括號),運算子(以括號為分界點)在棧內遵循越往棧頂優先順序不降低的原則進行排列。

(2)從右至左掃瞄中綴表示式,從右邊第乙個字元開始判斷:

如果當前字元是數字,則分析到數字串的結尾並將數字串直接輸出。

如果是運算子,則比較優先順序。如果當前運算子的優先順序大於等於棧頂運算子的優先順序(當棧頂是括號時,直接入棧),則將運算子直接入棧;否則將棧頂運算子出棧並輸出,直到當前運算子的優先順序大於等於棧頂運算子的優先順序(當棧頂是括號時,直接入棧),再將當前運算子入棧。

如果是括號,則根據括號的方向進行處理。如果是向右的括號,則直接入棧;否則,遇向左的括號前將所有的運算子全部出棧並輸出,遇右括號後將向左、向右的兩括號一起出棧(並不輸出)。

(3) 重複上述操作(2)直至掃瞄結束,將棧內剩餘運算子全部出棧並輸出,再逆綴輸出字串。中綴表示式也就轉換為字首表示式了。

例項分析

將中綴表示式「1+((2+3)*4)-5」轉換為字首表示式。

中綴表示式

字首表示式

(棧尾)運算子棧(棧頂)說明5

5空5,是數字串直接輸出-5

--,棧內無運算子,直接入棧)5

-)),直接入棧

45 4

-)4,是數字串直接輸出

*5 4

-)**,棧頂是括號,直接入棧

)5 4

- ) * )

),直接入棧

35 4 3

- ) * )

3,是數字串直接輸出

+5 4 3

- ) * ) +

+,棧頂是括號,直接入棧

25 4 3 2

- ) * )+

2,是數字串直接輸出

(5 4 3 2+

- ) *

(,與棧裡最後乙個)抵消,並釋放它們之間的+

(5 4 3 2+*

-(,方法與上類同,請參考下一目錄

+5 4 3 2+*

-++,優先順序大於等於棧頂運算子,直接入棧

15 4 3 2+*1

-+1,是數字串直接輸出

空5 4 3 2+*1±

空掃瞄結束,將棧內剩餘運算子全部出棧並輸出

空- + 1 * + 2 3 4 5

空逆綴輸出字串

演算法實現

將乙個普通的中綴表示式轉換為逆波蘭表示式的一般演算法是:

首先需要分配2個棧,乙個作為臨時儲存運算子的棧s1(含乙個結束符號),乙個作為存放結果(逆波蘭式)的棧s2(空棧),s1棧可先放入優先順序最低的運算子#,注意,中綴式應以此最低優先順序的運算子結束。可指定其他字元,不一定非#不可。從中綴式的左端開始取字元,逐序進行如下步驟:

(1)若取出的字元是運算元,則分析出完整的運算數,該運算元直接送入s2棧。

(2)若取出的字元是運算子,則將該運算子與s1棧棧頂元素比較,如果該運算子(不包括括號運算子)優先順序高於s1棧棧頂運算子(包括左括號)優先順序,則將該運算子進s1棧,否則,將s1棧的棧頂運算子彈出,送入s2棧中,直至s1棧棧頂運算子(包括左括號)低於(不包括等於)該運算子優先順序時停止彈出運算子,最後將該運算子送入s1棧。

(3)若取出的字元是「(」,則直接送入s1棧頂。

(4)若取出的字元是「)」,則將距離s1棧棧頂最近的「(」之間的運算子,逐個出棧,依次送入s2棧,此時拋棄「(」。

(5)重複上面的1~4步,直至處理完所有的輸入字元。

(6)若取出的字元是「#」,則將s1棧內所有運算子(不包括「#」),逐個出棧,依次送入s2棧。

完成以上步驟,s2棧便為逆波蘭式輸出結果。不過s2應做一下逆序處理。便可以按照逆波蘭式的計算方法計算了!

例項分析

下面以(a+b)*c為例子進行說明:

(a+b)c的逆波蘭式為ab+c,假設計算機把ab+c按從左到右的順序壓入棧中,並且按照遇到運算子就把棧頂兩個元素出棧,執行運算,得到的結果再入棧的原則來進行處理,那麼ab+c的執行結果如下:

1)a入棧(0位置)

2)b入棧(1位置)

3)遇到運算子「+」,將a和b出棧,執行a+b的操作,得到結果d=a+b,再將d入棧(0位置)

4)c入棧(1位置)

5)遇到運算子「」,將d和c出棧,執行dc的操作,得到結果e,再將e入棧(0位置)

經過以上運算,計算機就可以得到(a+b)*c的運算結果e了。

字首,中綴,字尾表示式轉化

中綴表示式轉字尾表示式 中綴表示式 1 2 3 4 5 1.直接轉換法 首先確定表示式的運算順序,然後加括號 1 2 3 4 5 然後從最裡面的一層括號開始運算,轉換成字尾表示式方法 去掉括號,運算元在左,操作符在右 2.利用表達樹 將表示式轉換為表達樹,然後後序遍歷 表示式轉換為表達樹方法 運算元...

字首 中綴 字尾表示式

它們都是對表示式的記法,因此也被稱為字首記法 中綴記法和字尾記法。它們之間的區別在於運算子相對與運算元的位置不同 字首表示式的運算子位於與其相關的運算元之前 中綴和字尾同理。舉例 3 4 5 6 就是中綴表示式 3 4 5 6 字首表示式 3 4 5 6 字尾表示式 中綴表示式 中綴記法 中綴表示式...

字首 中綴 字尾表示式

最近筆試的過程中老是有中綴轉換為字首,或是中綴轉換為字尾的問題,資料結構學了這麼久真的是記不清了,今天重新複習了一下,藉此機會總結一下 中綴 我們正常理解的表示式的書寫方式 字首 操作符全部位於運算元的前面,運算元的順序為從右到左依次壓棧的順序,操作符為從左到右依次壓棧的順序 字尾 不包含括號,運算...