【講古堂】表達式求值

【講古堂】表達式求值

dubenju@126.com 2015/12/27)算法

 

什麼是表達式

表達式是由數字,操做符,變量,常量等有意義地組合而成並能求得結果的式子。spa

例如:對象

32 + ( ( 9 * Celsius ) / 5 )遞歸

4 + 2 * 55 / 2.5token

組成表達式的信息種類繁多,這裏只討論數字表達式,即表達式由如下要素構成:get

數字、操做符、變量、常量。數學

 

數字

不考慮進制的話,一般指十進制數,小數的時候是有小數點的。數字一般是以被操做對象的身分出如今表達式中的,叫作操做數。it

 

操做符

表示對操做數進行哪一種操做的符號叫作操做符,被操做的值叫作操做數,對操做數進行操做的過程稱爲表達式求值。根據操做對象的個數分爲一元操做符和二元操做符。變量

一元操做符,操做只應用於單一操做數。例如:23!-n。二叉樹

操做應用於兩個操做數的叫二元操做符。例如:6*2一、29/十一、6.9+19.八、21.1-2.8

優先級

相對其餘操做符,每一個操做符都有一個優先級,優先級高的操做符比優先級低的操做符優先應用。通常的優先級是這樣設置的:

分組操做符()具備最高優先級。

一元操做符-+比乘除模的優先級高。

次方乘除模比加減法的高。

操做數的類型變換

類型變換是指操做的過程當中操做數的類型發生變化的現象。

好比:

1/3

1.5/0.3

 

變量與常量

變量是指值能夠變化的量。好比x+5中的x。

常量是指通常不發生變化並表明某一數值的量。好比:pi=3.1415926。

 

表達式的遞歸

這裏所謂的遞歸是指一個表達式的結果能夠做爲另外一表達式的操做數。

例如:

1 + 2 * 3

        2 * 3

1 + 6

 

表達式的表示方法

中綴表示

1 + x * 3 + 4 / x

操做符是以中綴形式處於操做數的中間(例:3 + 4)。中綴表達式不容易被計算機解析,但由於它符合人們的廣泛用法,被許多程序語言使用。至關於語法樹的中序遍歷獲得的結果。

 

前綴表示(波蘭式)

+ + 1 * x 3 / 4 x

操做符置於操做數的前面。若是操做符的元數(arity)是固定的,則語法上不須要括號仍然能被無歧義地解析。波蘭式是波蘭數學家揚·武卡謝維奇1920年代引入的,用於簡化命題邏輯。至關於語法樹的前序遍歷獲得的結果。

 

後綴表示(逆波蘭式)

1 x 3 * + 4 x / +

操做符置於操做數的後面。逆波蘭記法不須要括號來標識操做符的優先級。易於程序實現。至關於語法樹的後序遍歷獲得的結果。

 

表達式的分解parse

把表達式分解成不可再細分的基本元素的過程。

記號(token)的類型

變量variable

數值number

操做符operator

 

字符0-9和小數點.的話則是數值型。

是預先登記的變量的話則是變量型(常量等同於變量)。

如果操做符的話則是操做符型。

上述之外的話則是不正確的類型。

 

表達式的分析

語法檢查

語法錯誤就是表達式沒有遵循分析程序的嚴格規則。多數狀況下,語法錯誤都是人爲錯誤,好比輸入失誤等,如下表達式是非法的10**8(10-5)*9)/8

 

表達式求值

基於中綴表示的表達式求值

分別針對操做數和操做符構建表達式,必要時採用遞歸的方式。因爲實現起來比較複雜,多不採用,故不做細述。

 

基於前綴表示的表達式求值

對於解析後的記號,從後向前進行,若是掃描到操做數,則壓進棧,若是掃描到操做符,則根據操做符的操做數個數從棧中彈出相應個數的操做數來進行相應的操做,並將結果壓進棧,當掃描結束後,棧的棧頂就是表達式結果。

 

基於逆波蘭表示的表達式求值

針對逆波蘭,能夠用一個棧來實現計算,掃描從左往右進行,若是掃描到操做數,則壓進棧,若是掃描到操做符,則根據操做符的操做數個數從棧中彈出相應個數的操做數來進行相應的操做,並將結果壓進棧,當掃描結束後,棧的棧頂就是表達式結果。

 

調度場算法

中綴表達式轉換成後綴表達式

  既然中綴表達式對於計算機的運算並不便利,而前綴後綴表達式的計算相對簡單方便。所以,找到一種途徑將中綴表達式轉換成前綴後綴表達式就十分重要。實際上,兩者的轉換算法看起來也很像一個逆過程。所以,咱們着重討論中綴轉後綴。

從理論上講,已知一棵二叉樹的中序遍歷序列,要求出它的後序遍歷序列是不惟一的,即文法是有多義性的。可是,在這裏加上了優先級這一限制條件,轉換就變得惟一了。

所謂的調度場算法是操做數直接輸出,操做符的話要和棧內的操做符進行比較,優先級高的出棧輸出,而後當前操做符入棧。在最後,把棧內剩餘的所有輸出。這裏的棧起到了調度場的做用。

 

中綴表達式轉換成前綴表達式

  中綴表達式轉換成前綴表達式和中綴表達式轉換成後綴表達式十分相似,只須要將掃描方向由前日後變成由後往前,將'('改成')',')'改成'(',注意其中一個判斷優先級的地方須要由>=變成>便可。

相關文章
相關標籤/搜索