計算器實例正則表達式
1、文字思路分析算法
拿到一個表達式,例如 ‘3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)’,經過這個表達式,咱們除了考慮到數學的運算法則以外,還應該考慮到輸入表達式過程存在的輸入格式問題框架
一、格式問題:表達式中存在空格,就要去除空格函數
二、運算法則:有括號先去括號,先計算括號裏面的沒有括號的表達式;先算乘除再算加減;正負號問題,正負得負,負負得正spa
三、運用正則表達式去匹配表達式中的對應的項,而後計算code
四、每一項計算出來都得反饋回那一項所在的地方blog
五、有重複的東西,須要用到循環ip
2、分模塊進行計算(代碼)rem
exp = '3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)' new_exp = exp.replace(' ','') print(new_exp)
運行結果:數學
3+(-80/2)+24*5-(18/3+4*(90/15-100)-3)
先用正則表達式找出括號裏面沒有括號的項
ret = re.search('\([^()]+\)',new_exp) if ret: exp_no_bracket = ret.group() # 篩選出括號裏面沒有括號的表達式 print(exp_no_bracket)
運行結果:
(-80/2)
將括號裏面沒有括號的項去括號,而後找出單純的乘除項,利用調用函數的方法,計算乘除結果
def cal_exp_no_bracket(ex): # ex是括號裏面沒有括號的項 ex = ex.strip('()') # 將裏面沒有括號的項的括號去除 # 計算先乘除後加減 ret = re.search('\d+\.?\d*[*/]-?\d+\.?\d*',ex) # 利用正則表達式找第一個出現的乘除的項 if ret: ex_son = ret.group() # 子表達式,最簡單的只有乘除法 print(ex_son) ....
....
ret = cal_exp_no_bracket(exp_no_bracket) # 調用計算括號裏面沒有括號的函數
new_exp = new_exp.replace(exp_no_bracket,ret) # 將計算括號裏面沒有括號的最後的值代替對應的項
print(new_exp)
運行結果:
80/2
計算原子表達式,即最簡的原子形式表達式
def cal_ex_son(ex_son): if '/' in ex_son: a,b, = ex_son.split('/') return str(float(a)/float(b)) elif '*' in ex_son: a,b, = ex_son.split('*') return str(float(a) * float(b)) ....
.... ret = cal_ex_son(ex_son) # 調用計算原子表達式的函數 print(ret) new_ex = ex.replace(ex_son,ret) # 將最終計算的值替代原來括號裏面沒有括號的那一項
運行結果應該是:
-40.0
3+-40.0+24*5-(18/3+4*(90/15-100)-3)
ret = re.findall('-?\d+\.?\d*',ex) sum = 0 for i in ret: sum += float(i) return str(sum)
正負得負,負負得正
# 正負符號的處理,正負得負,負負得正 def dealwith(exp): exp = exp.replace('+-','-') exp = exp.replace('--','+') return exp ....
.... new_exp = dealwith(new_exp) print(new_exp)
運行結果應該是:
3-40.0+24*5-(18/3+4*(90/15-100)-3)
經過函數的調用和嵌套,一步一步計算
# 要計算的表達式 exp = '3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)' # 去空格 new_exp = exp.replace(' ','') print(new_exp) res = remove_bracket(new_exp) print(res)
3、計算器總模塊代碼
以上的2和3和4點只是計算了第一個匹配到括號裏面沒有括號的項,以及第一個出現乘除的項,和第一個出現加減法的項,要計算所有的這樣的項,須要利用循環,去實現,主要式尋找和計算括號裏面沒有括號的項,還有尋找和計算簡單的乘除以及加減式子須要反覆尋找計算,最後整理的計算器的大體框架:
import re # 導入re模塊,正則表達式須要 # 正負符號的處理,正負得負,負負得正 def dealwith(exp): exp = exp.replace('+-','-') exp = exp.replace('--','+') return exp # 計算原子形式的表達式,兩個數的乘除法 def cal_ex_son(ex_son): if '/' in ex_son: a,b, = ex_son.split('/') return str(float(a)/float(b)) elif '*' in ex_son: a,b, = ex_son.split('*') return str(float(a)*float(b)) else: print('全部的乘除式子都計算好了') # 計算最簡的括號裏面沒有括號的式子,先計算乘除法,再計算加減 def cal_exp_no_bracket(ex): # ex是括號裏面沒有括號的項 ex = ex.strip('()') # 將裏面沒有括號的項的括號去除 # 計算先乘除後加減 while True: # 利用循環找到括號裏面再也不有括號的項 ret = re.search('\d+\.?\d*[*/]-?\d+\.?\d*',ex) # 利用正則表達式找第一個出現的乘除的項 if ret: # 說明表達式中還有乘除法 ex_son = ret.group() # 子表達式,最簡單的只有乘除法,原子形式 print('匹配到只有乘除法的項: ',ex_son) ret = cal_ex_son(ex_son) # 調用計算原子表達式的函數 ex = ex.replace(ex_son,ret) # 將最終計算的值替代原來括號裏面沒有括號的那一項 ex = dealwith(ex) else: # 說明表達式中沒有乘除法,而後計算加減法 ret = re.findall('-?\d+\.?\d*',ex) sum = 0 for i in ret: sum += float(i) return str(sum) # 篩選出括號裏面沒有括號的表達式,而且開始計算 def no_bracket_in_bracket(new_exp): while True: # 利用循環找到全部的一層一層裏面沒有括號的項 ret = re.search('\([^()]+\)',new_exp) if ret: exp_no_bracket = ret.group() # 篩選出括號裏面沒有括號的表達式 print('匹配到內部再也不有括號的項: ',exp_no_bracket) ret = cal_exp_no_bracket(exp_no_bracket) # 調用計算括號裏面沒有括號的項 print(ret) new_exp = new_exp.replace(exp_no_bracket,ret) # 將計算括號裏面沒有括號的最後的值代替對應的項 new_exp = dealwith(new_exp) print(new_exp) else: print('表達式中沒有括號了: ',new_exp) ret = cal_exp_no_bracket(new_exp) print(ret) break # 主程序,要計算的表達式 exp = '3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)' # 去空格 new_exp = exp.replace(' ','') print(new_exp) res = no_bracket_in_bracket(new_exp) print(res)
運行結果:
3+(-80/2)+24*5-(18/3+4*(90/15-100)-3) 匹配到內部再也不有括號的項: (-80/2) 匹配到只有乘除法的項: 80/2 -40.0 3-40.0+24*5-(18/3+4*(90/15-100)-3) 匹配到內部再也不有括號的項: (90/15-100) 匹配到只有乘除法的項: 90/15 -94.0 3-40.0+24*5-(18/3+4*-94.0-3) 匹配到內部再也不有括號的項: (18/3+4*-94.0-3) 匹配到只有乘除法的項: 18/3 匹配到只有乘除法的項: 4*-94.0 -373.0 3-40.0+24*5+373.0 表達式中沒有括號了: 3-40.0+24*5+373.0 匹配到只有乘除法的項: 24*5 456.0 None Process finished with exit code 0