1. 程式人生 > >使用Python list通過遞迴實現一個表示式計算器

使用Python list通過遞迴實現一個表示式計算器

因為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檔案就能運行了