字首表示式 中綴表示式 字尾表示式的區別

2021-08-20 10:23:55 字數 2763 閱讀 2996

一、三者的概念(參考維基百科)

1.1中綴表示式

中綴表示式是符合人類直覺的一種表達方式,其特點是操作符(二元操作符)在中間,運算元在兩側。

例如 3 + 4 ,   5 - 6 * 7,     (5 - 6) *7等。括號的存在會影響計算步驟的執行。

1.2字首表示式(又稱波蘭表示式)

字首表示式(以及字尾表示式)是符合計算機思維的一種表達方式。

將1.1的幾個中綴表示式轉換成字首表示式如下:

+ 3 4 ,   - 5 * 6 7,     * - 5 6 7

這種表示式有乙個特點,由它的發明人波蘭

數學家揚·武卡謝維奇

指出,這種方式是無需括號的表達方式,即括號不影響計算順序

如 * (- 5 6) 7 與 * - 5 6 7是一樣的。這裡需要說明的是,無需括號的這種特點是有適用範圍的,當操作符作用的運算元的個數可變時,如階乘一元 + - * /等為二元時,就需要用括號來表示操作順序了。

1.3字尾表示式(逆波蘭表示式)

字尾表示式也是符合計算機思維的一種表達方式,與字首表示式具有同樣的特點,只是順序相反(在程式設計實現上還有些細微差別,),但是我們在程式設計實現的時候對乙個表示式的字串,採用字尾表達的話,字串從前往後讀取並處理,符合我們的程式設計習慣,所以常常以如何求值字尾表示式或將中綴表示式轉換成字尾表示式來作為教學。

將1.1的幾個中綴表示式轉換成字首表示式如下:

3 4 +,    5 6 7 * - , 5 6 - 7 * 

二、中綴表示式與字尾表示式的比較(基於二元操作符下的討論)

2.1中綴表示式的樸素演算法

已知運算子是有運算順序的,對於乙個沒有括號的表示式(運算元記為n, 操作符記為op):

n1  op1  n2  op2  n3  op3  n4  ...  opk  nk+1

我們知道,當計算機線性讀取(即從左到右讀取該字串時)其遇到op1,此時它並不能確定是否可以立即做運算,因為op1優先順序不一定是最高的,所以它必須得遍歷op1 到 opk找到最高端的opj,並做(nj opj nj+1)的運算。

這一步驟可歸納如下:遍歷整個字串,找到當前最高端的操作符opj,進行運算,所有運算子均參與運算。

每一步的時間複雜度為(假設當前字串長度為n): n, 下一步則為n - 3 + 1 = n -2。

所以整個演算法複雜度為等差數列求和為o(n^2)。

這也是為什麼符合人類直覺的表示式卻不適合用計算機來處理。

2.2具有迷惑性的中綴表示式求值演算法(本質上是將中綴表示式轉換成字尾表示式再處理的一種方式)

/*

此演算法摘自《中綴和字尾算術表示式的分析比較》劉愛貴 高能物理研究所計算中心 2023年

*/

int middexpression(char *exp)

ch=*++exp;

}else}}

result = opnd->pop();

return(result);

}

這裡我們重點關注一下該演算法時如何處理操作符的(此處摘抄參考文章的原文):

為了實現算符優先演算法,要使用兩個工作棧。乙個稱為

optr,

用以寄存運算子;另乙個稱為

opnd

,用以寄存運算元或運算結果,它的基本思想於字尾表示式計算的不同在於:當讀取到運算子時並不可能作相應運算,必須先比較運算子棧中棧頂元素與當前運算子的優先順序。若為『<

』則運算子入棧;若為『

=』則說明是一對括號,需脫括號;若『

>

』則作相應運算並將結果入棧。

這裡再列出一下將中綴表示式轉換成字尾表示式的演算法(摘自將中綴表示式轉化為字尾表示式):

規則:從左到右遍歷中綴表示式的每個數字和符號,若是數字就輸出,即成為字尾表示式的一部分;若是符號,則判斷其與棧頂符號的優先順序,是右括號或優先順序低於棧頂符號(乘除優先加減)則棧頂元素依次出棧並輸出,並將當前符號進棧,若是左括號或優先順序高於或等於棧頂符號則直接進棧,一直到最終輸出字尾表示式為止。

這裡可以看到所謂的上述兩個演算法對操作符的處理其實是大同小異的。只不過所謂的中綴表示式求值演算法將中綴表示式轉換成字尾表示式的同時,也同在進行操作符的運算了。我認為其具有迷惑性的原因在於,不少部落格用中綴表示式求值演算法為該演算法命名,如果不去解構該演算法的話,會有這樣一種迷惑,為什麼中綴表示式求值演算法已經是o(n)的複雜度了,我們還需要去討論字尾表示式。但是通過結構該演算法後,我們可以看到這個演算法其實就是將中綴表示式轉換成字尾表示式與字尾表示式的計算結合在了一起。

需要說明的是,我認為劉愛貴先生的這篇**在最後的時間複雜度分析是存在些許問題的,他將該演算法的複雜度分析成o(n^2)了,實際上我認為是o(n),但是我的分析過程並不是太嚴謹,也可能有疏漏。

2.3字尾表示式求值演算法

此時的演算法思想已經比較簡單了:從前往後讀字尾表示式,運算元則壓入棧中,若遇到操作符就去操作符彈出棧頂的兩個運算元做運算並將結果壓入棧,直到所有操作符均遍歷完。

關於中綴表示式轉換成字尾表示式的方式主要有以下兩種:1.排程場演算法(可參考維基百科),2.2中提到的演算法思想是針對二元表示式的一種簡化版本。2.將中綴表示式轉換成表示式樹再進行後序遍歷得到字尾表示式。

2.4字首表示式與字尾表示式也是大同小異,只不過順序有變,這裡不再做分析。

中綴表示式 字首表示式 字尾表示式

中綴表示式 中綴記法 中綴表示式是一種通用的算術或邏輯公式表示方法,操作符以中綴形式處於運算元的中間。中綴表示式是人們常用的算術表示方法。雖然人的大腦很容易理解與分析中綴表示式,但對計算機來說中綴表示式卻是很複雜的,因此計算表示式的值時,通常需要先將中綴表示式轉換為字首或字尾表示式,然後再進行求值。...

中綴表示式 字尾表示式 字首表示式

正如我們常常潛意識認為我們所說的數字都是十進位制,對於數字的其他進製感覺不正確一樣,其實只是我們不熟悉而已,其他進製其實也不過就是一種對資料的表達方式而已。對於我們的表示式也是一樣。eg 表示式2 3 5 7 我們上面所看到的也就是我們平時常用的書寫表示式的方式就是我們所謂的 中綴表示式 字首表示式...

字首表示式 中綴表示式 字尾表示式。

表示式 就是式子。是由數字 算符 數字分組符號 自由量和約束量組成的。人們一般習慣寫出來的式子,叫做中綴表示式。因為在計算機中,不方便表達 數字分組符號。所以 波蘭人發明了一種把去符號化的表示式。字首表示式 字首表示式 沒有括號,算符在前 數字在後。波蘭數學家發明,為了紀念,又叫做波蘭式。跟其對應,...