學習來自: 感謝!
思路:考慮的四則運算符號 : ["+", "-", "*", "/", "(", ")"]
獲取表示式字串 --》表示式切分 (請注意區分 減號"-", 與負號"-" ) --》
先出初切:
formula_list = [i for i in re.split('(\-\d\.?\d*)', formula) if i]然後再判定:
if re.search('[\+\-\*\/\(]$', final_formula[-1]):其他正常切分就行:
item_split = [i for i in re.split('([\+\-\*\/\(\)])', item) if i]
得到合適的 字元子串 --》 區分 屬於 數字棧 還是 操作符棧 -》存好後
運算邏輯
遍歷表示式split後結果,如果數字來了需要壓棧,進入 num_stack,
如果運算子來了,判定:
第乙個運算子 直接壓棧
新的後面的運算子來了,先拿出之前的運算子棧中最後的運算子彈出,比較優先順序
如果優先順序相同,數字棧彈出後兩個元素與老運算子操作 -> 得到的結果壓入數字棧
如果優先順序不同,新的運算子壓棧
注意,如果老運算子彈出為「(」, 新運算子目前為「)」,-> 彈出老的"(", 丟棄新的「)」
所有item結束後,數字棧和運算子棧中可能還有元素,再搞一波,最後結果在 num_stack中
**:
import re
def calculate(n1, n2, operator):
if operator == "+":
result = n1 + n2
elif operator == "-":
result = n1 - n2
elif operator == "*":
result = n1 * n2
elif operator == "/":
result = n1 / n2
else:
raise exception("operator is not support now...")
return result
def is_operator(e):
operators = ["+", "-", "*", "/", "(", ")"]
return true if e in operators else false
def formula_format(formula):
"""步驟需要處理的是區分橫槓『-』是代表負數還是減號
"""formula = re.sub(' ', '', formula)
# 以 '橫槓數字' 分割, -> \- 表示匹配橫槓開頭; \d+ 表示匹配數字1次或多次;\.?表示匹配小數點0次或1次;\d*表示匹配數字1次或多次。
formula_list = [i for i in re.split('(\-\d\.?\d*)', formula) if i]
final_formula =
for item in formula_list:
# 第乙個是以橫槓開頭的數字(包括小數)final_formula。即第乙個是負數,橫槓就不是減號
if len(final_formula) == 0 and re.search('^\-\d+\.?\d*$', item):
continue
if len(final_formula) > 0:
# 如果final_formal最後乙個元素是運算子['+', '-', '*', '/', '('], 則橫槓數字不是負數
if re.search('[\+\-\*\/\(]$', final_formula[-1]):
continue
# 剩下的按照運算子分割開
item_split = [i for i in re.split('([\+\-\*\/\(\)])', item) if i]
final_formula += item_split
return final_formula
def decision(tail_op, now_op):
""":param tail_op: 運算子棧最後乙個運算子
:param now_op: 算式列表取出當前運算子
:return: 1 彈棧, 0 彈出運算子棧最後乙個元素, -1 入棧
"""# 運算子等級
rate1 = ["+", "-"]
rate2 = ["*", "/"]
rate3 = ["("]
rate4 = [")"]
if tail_op in rate1:
if now_op in rate2 or now_op in rate3:
# 運算子優先順序不同
return -1 # 把當前取出的運算子壓棧 "1+2+3"
else:
return 1 # 否則運算子棧中最後的 運算子彈出,進行計算
elif tail_op in rate2:
if now_op in rate3:
return -1
else:
return 1
elif tail_op in rate3:
if now_op in rate4:
return 0 # ( 遇上 ) 需要彈出 (,丟掉 )
else:
return -1 # 只要棧頂元素為(,當前元素不是)都應入棧
else:
return -1
# 主函式 -> 遍歷算式列表中的字元,決定入棧彈棧操作
def final_cal(formula_list):
num_stack =
op_stack =
for e in formula_list:
operator = is_operator(e)
if not operator:
# 數字棧 -> 轉為浮點數
a = 2
else:
# e 開始進入 運算子棧, -> 判斷
while true:
a = 1
if len(op_stack) == 0: #第乙個運算子來了,都得入棧
break
# 後面運算子來了,需要判斷入棧,or 出棧。
pop_oper = op_stack[-1]
tag = decision(op_stack[-1], e)
if tag == -1: # 壓棧
break
elif tag == 0: #彈出運算子棧內最後乙個 "(", 丟掉當前的 ")", 進入下次迴圈
op_stack.pop()
break
elif tag == 1: # 運算子棧彈出最後乙個運算子,數字棧彈出最後兩個元素,進行計算
op = op_stack.pop()
num2 = num_stack.pop()
num1 = num_stack.pop()
# 計算後結果 --> 壓入數字棧
# 處理大迴圈結束後 數字棧和運算子棧中可能還有元素 的情況
while len(op_stack) != 0:
op = op_stack.pop()
num2 = num_stack.pop()
num1 = num_stack.pop()
return num_stack, op_stack
if __name__ == "__main__":
# formula = "1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))"
formula = "1 - (2 + (-6 + (-2))) "
formula_list = formula_format(formula)
result, _ = final_cal(formula_list)
print('result = ', result)
結果:
result = [7.0]
四則運算計算器
今天做個帶視窗的c 四則運算計算器 輸入中綴表示式 自然表示式 可以用list來放 先把它變成字尾表示式 逆波蘭表示式 用乙個棧放運算子,另乙個棧放字尾表示式 運算子優先順序 1 2 3 4 從左到右遍歷中綴表示式 計算字尾表示式 從左到右掃瞄字尾表示式,如果是數字,放入數字棧。如果是符號,從數字棧...
簡單的四則運算計算器
include stdio.h include stdlib.h include string.h define string length 1000 define number length 40 結構體定義 struct symbol symbol head null,temp null str...
棧實現計算器(簡單四則運算)
主要是通過定義乙個數棧和乙個符號棧,並根據給出的計算式進行拆分,迴圈判斷是數字還是符號,考慮數字的連續性和符號計算的優先順序,具體實現如下 package com.pangzi.stucture public class calculator else else elseelse 讓index 1,...