功能: 通過輸入一個長字符串得到結果
包括函數:
format_string(string):
將傳入的字符串string中的類似於"--","-+","+-","==","*+","/+" 格式化
calc_mul_div(string):
對傳入的字符串進行乘法、除法計算,返回僅有加、減的表達式
calc_add_sub(string)
對傳入的字符串進行加、減運算,返回計算結果
設計思路:
1 將表達式先進行去括號,返回不包含括號的單一表達式
2 將得到的單一表達式先進行乘、除運算,並用字符串替換的方式將計算表達式替換爲計算結果。直到表達式只剩下加、減運算符號。
3 將第二步計算的結果再進行加、減運算,並進行字符串替換,直到計算出表達式結果
4 將第三步計算的結果替換第一步的表達式。
包括函數:
format_string(string):
將傳入的字符串string中的類似於"--","-+","+-","==","*+","/+" 格式化
calc_mul_div(string):
對傳入的字符串進行乘法、除法計算,返回僅有加、減的表達式
calc_add_sub(string)
對傳入的字符串進行加、減運算,返回計算結果
設計思路:
1 將表達式先進行去括號,返回不包含括號的單一表達式
2 將得到的單一表達式先進行乘、除運算,並用字符串替換的方式將計算表達式替換爲計算結果。直到表達式只剩下加、減運算符號。
3 將第二步計算的結果再進行加、減運算,並進行字符串替換,直到計算出表達式結果
4 將第三步計算的結果替換第一步的表達式。
5 只要表達式中包含"(",重複以上步驟直到表達式不包含任何括號
流程圖:
源碼:
#!/usr/bin/env python # -*- coding: utf-8 -*- import re # 格式化字符串 def format_string(string): string = string.replace("--", "+") string = string.replace("-+", "-") string = string.replace("++", "+") string = string.replace("+-", "-") string = string.replace("*+", "*") string = string.replace("/+", "/") string = string.replace(' ', '') return string # 檢查表達式合法性 def check_expression(string): check_result = True # 括號是否匹配 if not string.count("(") == string.count(")"): print("表達式錯誤,括號未閉合!") check_result = False if re.findall('[a-z]+', string.lower()): print("表達式錯誤,包含非法字符!") check_result = False return check_result # 計算乘 、除法 def calc_mul_div(string): # 從字符串中獲取一個乘法或除法的表達式 regular = "\d+\.{0,}\d{0,}[\*\/][\-]{0,}\d+\.{0,}\d{0,}" # 如果還能找到乘或除法表達式 while re.findall(regular, string): # 獲取表達式 expression = re.search(regular, string).group() # 如果是乘法 if expression.count("*"): # 獲取要計算的兩個數 x, y = expression.split("*") # 計算結果 mul_result = str(float(x) * float(y)) # 將計算的表達式替換爲計算結果值 string = string.replace(expression, mul_result) # 格式化一下 string = format_string(string) # 如果是除法 if expression.count("/"): # 獲取要計算的兩個數 x, y = expression.split("/") # 計算除法 div_result = str(float(x) / float(y)) # 用結果替換表達式 string = string.replace(expression, div_result) string = format_string(string) return string # 計算加、減法 def calc_add_sub(string): # 定義正則表達式 add_regular = "[\-]{0,}\d+\.{0,}\d{0,}\+[\-]{0,}\d+\.{0,}\d{0,}" sub_regular = "[\-]{0,}\d+\.{0,}\d{0,}\-[\-]{0,}\d+\.{0,}\d{0,}" # 開始加法 while re.findall(add_regular, string): # 把所有的加法都算完,獲取所有加法表達式 add_list = re.findall(add_regular, string) for add_str in add_list: # 獲取兩個加法的數 x, y = add_str.split("+") add_result = "+" + str(float(x) + float(y)) string = string.replace(add_str, add_result) string = format_string(string) # 開始減法 while re.findall(sub_regular, string): sub_list = re.findall(sub_regular, string) for sub_str in sub_list: numbers = sub_str.split("-") # -3-5的情況split會返回3個值 if len(numbers) == 3: result = 0 for v in numbers: if v: result -= float(v) else: x, y = numbers result = float(x) - float(y) # 替換字符串 string = string.replace(sub_str, "+" + str(result)) string = format_string(string) return string if __name__ == "__main__": source = "1 - 2 * ( (60-30 +(-9-2-5-2*3-5/3-40*4/2-3/5+6*3) * (-9-2-5-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )" if check_expression(source): print("source: ", source) print("eval result: ", eval(source)) while source.count("(") > 0: # 格式化 source = format_string(source) # 去括號,得到括號的字符串,結果如:(30+6/3) strs = re.search('\(([/-]*\d+\.*\d*[\+\-\*/]+)+\d+\.*\d*\)', source).group() # 將括號的表達式進行乘、除運算 replace_str = calc_mul_div(strs) # 將運算的結果在進行加、減運算 replace_str = calc_add_sub(replace_str) # 將括號的字符串替換爲計算結果,結果包含(),替換時去掉():[1:-1] source = format_string(source.replace(strs, replace_str[1:-1])) else: # 沒有括號就到最後單一表達式了 replace_str = calc_mul_div(source) # 算乘除 replace_str = calc_add_sub(replace_str) # 算加減 source = source.replace(source, replace_str) print("my result: ", source.replace("+", ""))