表示式求值相關演算法

2021-10-01 08:51:19 字數 3606 閱讀 9577

實現對乙個數學表示式的求值,例如:1+2*(3+4)這個表示式的值為15

這個問題主要要分為如下幾個步驟:

語法分析: 將字串表示式轉化為數字和操作符的 token 陣列,['1', '+', '2', '*', '(', '3', '+', '4', ')']轉逆波蘭表示式: 將中綴表示式轉字尾表示式,['1', '2', '3', '4', '+', '*', '+']逆波蘭表示式求值:15

逆波蘭表示式轉二叉樹: 條件表示式中,二叉樹的求值能提前返回,能比逆波蘭表示式計算量更少

def

tokenizer

(expr)

: l =

len(expr)

i =0 tokens =

while i < l:

while expr[i]

==' '

: i +=

1if is_operator(expr[i]):

if i +

1== l:

return

none

if expr[i]

=='-'

:if tokens and

(not is_operator(tokens[-1

])andnot tokens[-1

]=='('):)

i +=

1else

: j = i +

1while j < l and

not is_operator(expr[j]

)and

not is_parenthesis(expr[j]):

j +=1)

i = j

else:)

i +=

1elif is_parenthesis(expr[i]):

) i +=

1else

: j = i

while j < l and

not is_operator(expr[j]

)and

not is_parenthesis(expr[j]):

j +=1)

i = j

return tokens

準備乙個棧來儲存運算子和 「(」

遍歷中綴表示式

如果是運算元,直接輸出

如果是 「(」,直接入棧

如果是 「)」,從棧中彈出元素輸出直到遇到 「(」

如果是運算子並且棧為空,直接入棧

如果是運算子並且棧不為空,從棧裡彈出元素輸出,直到棧頂優先順序低於當前運算子或者遇到 「(」

將棧裡剩餘的元素一次彈出輸出

op_priority =

defto_polish

(tokens)

: polish =

stack =

for token in tokens:

if is_operator(token)

:while stack and is_operator(stack[-1

])and op_priority[stack[-1

]]>= op_priority[token]:-

1]) stack.pop(

)elif token ==

'(':

elif token ==

')':

while stack and stack[-1

]!='(':-1

])stack.pop()if

not stack:

return

none

stack.pop(

)else

:while stack:-1

])stack.pop(

)return polish

準備乙個棧用來儲存中間結果

遍歷逆波蘭表示式

如果是運算元,直接入棧

如果是運算子,從棧頂取出運算子所需要的運算元個數,計算結果再次入棧

最後棧中只剩下乙個元素,即最終結果

op_handler =

defcalculate

(polish)

: stack =

for token in polish:

if is_operator(token)

: y = stack[-1

] stack.pop(

) x = stack[-1

] stack.pop(

)(x, y)

)else

:int

(token)

)return stack[-1

]

準備乙個棧用來儲存中間節點

遍歷逆波蘭表示式

如果是運算元,構造乙個運算元節點入棧

如果是運算子,構造乙個新的節點,從棧頂取兩個元素作為左右節點,新節點入棧

最後棧中只剩下乙個節點,即最終的 root 節點

class

node

:def

__init__

(self, val, left=

none

, right=

none):

self.left = left

self.right = right

self.val = val

def__str__

(self)

:return

str(self.left)

+", "

+str

(self.val)

+", "

+str

(self.right)

defto_binary_tree

(polish)

: stack =

for token in polish:

if is_operator(token)

: right = stack[-1

] stack.pop(

) left = stack[-1

] stack.pop())

else:)

return stack[-1

]

遞迴求值即可

def

calculate_binary_tree

(node):if

not is_operator(node.val)

:return

int(node.val)

return op_handler[node.val]

(calculate_binary_tree(node.left)

, calculate_binary_tree(node.right)

)

演算法 表示式求值

今天在網上看到dijkstra的雙棧算術表示式求值演算法,以前很早的時候知道通過算術棧和數值棧搞定的,這次用oc通過陣列實現了預期的效果.原理參考網上,原作者不詳 程式語言系統一般都內建了對算術表示式的處理,我們可以簡易的模仿一下算術表示式處理機制,思想不變,主要是實現方式略有不同。算術表示式可能是...

表示式求值(遞迴演算法)

問題描述 見下圖 程式 題目描述 表示式求值 遞迴演算法 表示式 1 可以是乙個項 2 也可以由多個項通過加減構成 項 1 項本身可以是乙個因子 2 項也可以由若干個因子通過乘除組成 因子 1 因子本身可以是乙個數字 2 因子也可以由表示式加上括號組成 include include include...

表示式求值

程式的說明見清華大學出版社 資料結構 c語言版 include include define stack init size 40 define stackincrement 20 define ok 1 define false 0 typedef structs stack typedef st...