實現對乙個數學表示式的求值,例如: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...