使用Python list通過遞迴實現一個表示式計算器
阿新 • • 發佈:2019-02-05
因為python list可以同時儲存不同的資料, 並且提供豐富的操作方案, 想想可以同時把數字和運算子號都儲存到列表中, 於是就誕生了使用列表寫個表示式計算器, 思路就是同時將數字和運算子儲存到列表, 然後從左向右計算所有乘除號兩邊的數值, 然後刪除兩個運算元和一個運算子, 再把運算結果儲存到剛才計算的位置, 然後再第二次迴圈計算剩下的加減法運算, 最有元組只剩下一個數, 輸出即結果,
檢查符號是否為運算子號
nums = "0123456789"
optrs = "+-*/="
def isoperator(expression, index):
'''判斷符號是運算子號還算是描述負數的符號'''
if nums.find(expression[index - 1]) != -1 and optrs.find(expression[index]) != -1:
return True
return False
將字串表示式轉換為列表
def gen_list(expression):
'''將輸入的字串表示式轉換為列表'''
units = []#儲存包含操作符和運算元的列表
start = 0#標記數字起點
expression = (expression if expression[len(expression) - 1 ] == "=" else expression + "=")
for i in range(len(expression)):
if (isoperator(expression, i)):
units.append(float(expression[start:i]))
units.append(expression[i])
start = i + 1
return units
計算只有簡單加減乘除的表示式
def base_calculate(expression, isFirst = True) :
'''計算只含有加減乘除的基本表示式'''
i = 0
while i < len(expression) - 3:
a = expression[i]#獲取運算元1
b = expression[i + 2]#獲取運算元2
optr = expression[i + 1]#或者運算子
tresult = None
if optr == "*":
tresult = a * b
elif optr == "/":
tresult = a / b
elif not isFirst and optr == "+":
tresult = a + b
elif not isFirst and optr == "-":
tresult = a - b
if tresult != None:
expression[i] = tresult#將第一個運算元替換問運算結果
del(expression[i + 1 : i + 3])#刪除運算子號和後一個運算元
else:
i += 2#下標偏移
if isFirst:
return base_calculate(expression, False)
else:
return expression[0]#返回結果
通過以上的方案已經能計算任意不含括號的加減乘除運算, 但是我想要功能個更NB一點, 要能計算帶括號的表示式, 怎麼實現呢, 同先計算乘除法一樣, 上面計算簡單表示式的方法寫成一個子函式, 然後再寫一個遞迴函式遞迴計算帶括號的表示式就OK了, 先計算最內部括號中的表示式, 然後將最內部的括號替換為計算後的結果, 在遞迴外部一層的, 最有留下的就是結果了
實現遞迴計算帶括號的表示式
def calculate(expression):
'''遞迴計算帶括號的表示式'''
if expression.find("(") == -1:#如果表示式不含符號, 直接返回計算結果
return base_calculate(gen_list(expression))
parathesis = []#做符號棧檢查括號匹配
for i in range(len(expression)):
if expression[i] == '(':#遇到左括號, 表示式起點
parathesis.append(i)#儲存左括號的下標
elif expression[i] == ')':#遇到右括號, 表示式終點, 遇到完整的一段表示式則遞迴計算
if len(parathesis) != 0:
subexp = expression[parathesis[-1] : i + 1][1 : -1]#擷取子表示式
if subexp.find("(") == -1:#如果子表示式不含有括號了則計算
result = base_calculate(gen_list(subexp))#計運算元表示式的結果
pre = expression[0 : parathesis[-1]]#括號前面的表示式
post = expression[i + 1 : ]#括號後面的表示式
expression = pre + str(result) + post#拼接為新的表示式
return calculate(expression)#遞迴計算
parathesis.pop()#刪除一個左括號
執行入口
while True:
#輸入表示式, 保證輸入合法
expression = input('input a expression:')
print(calculate(expression))
將以上程式碼按順序複製到python檔案就能運行了