Python利用正則表達式實現(xiàn)計算器算法思路解析
?。?)不使用eval()等系統(tǒng)自帶的計算方法
?。?)實現(xiàn)四則混合運算、括號優(yōu)先級解析
思路:
1、字符串預處理,將所有空格去除
2、判斷是否存在括號運算,若存在進行第3步,若不存在則直接進入第4步
3、利用正則表達式獲取最底層括號內(nèi)的四則運算表達式
4、將四則運算表達式進行預處理:表達式開頭有負數(shù)時,在表達式前加上一個0
5、利用re.split()、re.findall()方法,通過加減符號,對四則運算進行拆分為乘除運算式和數(shù)字,并保留對應的位置下標。
6、利用re.split()、re.findall()方法,通過乘除符號,將乘除式拆分為乘除符號與數(shù)字,然后進行計算,并返回數(shù)值。
7、通過re.split()、re.findall()保留的下標位置,將表達式還原。
8、完成所有乘除運算之后,返回進行加減運算。
9、完成加減運算后,返回表達式進行替代。
10、通過遞歸函數(shù),完成所有括號運算后。最后再完成一次四則運算即可完成所有運算。
注:在過程中,負數(shù)的處理存在三個要點:當負數(shù)出現(xiàn)在表達式開頭、負數(shù)前面存在減法、乘除式中存在負數(shù)且不在表達式開頭。
(1)當負數(shù)出現(xiàn)在表達式開頭:在前面加上一個0
?。?)負數(shù)前面存在減法:每次完成一次運算后需要進行一次符號檢查替換
?。?)乘除式中存在負數(shù)且不在表達式開頭:將負號移到表達式最開頭
#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author:Dang
import re
def update_formula(calc_list,calc_operator_list):
# 通過拆分后的表達式列表與符號列表重新組合
for index,item in enumerate(calc_list):
if index == 0:
formula = item
elif index != 0:
formula += calc_operator_list[index-1] + item
return formula
def negative_start_issue(formula):
#處理負數(shù)在括號內(nèi)表達式開頭的情形
calc_list = re.split("[+-]",formula) #通過+-符號將各個乘除運算分隔出來
calc_operator_list = re.findall("[+-]",formula)
for index,item in enumerate(calc_list):
if index == 0 and item == '': # 處理負號在開頭的問題
calc_list[index] = '0'
else:
calc_list[index] = item.strip()
formula = update_formula(calc_list,calc_operator_list)
return formula
def deal_unusual_issue(formula):
# 雙加減符號處理
formula = formula.replace(" ","") #去掉空格
formula = formula.replace("++","+")
formula = formula.replace("+-", "-")
formula = formula.replace("-+", "-")
formula = formula.replace("--", "+")
return formula
def deal_negative_issue(formula):
# 處理乘除運算中負數(shù)的計算問題(分前后位置兩種情況)
# 1.負數(shù)在后
m = re.search("[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0-9]*",formula)
# minus_pre = re.search("[0-9]+[.]*[0-9]*[*|/][-][0-9]+[.]*[0-9]*",formula).group()
# 注意匹配的必要項與非必要項,如:"[0-9]+[.][0-9]+[*|/][-][0-9]+[.][0-9]+"誤把非必要項當做必要項。
if m:
minus_pre = m.group()
minus_pro = "-"+minus_pre.replace("-","")
formula = formula.replace(minus_pre,minus_pro)
if "*-" in formula or "/-" in formula:
return deal_negative_issue(formula)
# 2.負數(shù)在前
formula = deal_unusual_issue(formula)
return formula
def multiply_divide(formula):
# print("[%s]"%formula,formula)
# 乘除計算
calc_list = re.split("[*/]", formula)
operator_list = re.findall("[*/]", formula) # 將乘號除號通過列表方式分隔出來
# print("sub_calc_list:", sub_calc_list)
# print("sub_operator_list:", sub_operator_list)
res = 0
for index2, i in enumerate(calc_list):
if index2 == 0:
res = float(i)
else:
if operator_list[index2 - 1] == '*': # 通過sub_operator_list中的index判斷到底是加法還是減法,
res *= float(i)
elif operator_list[index2 - 1] == '/':
res /= float(i)
return res
def add_abstract(formula):
# 加減計算
# 1.開頭位置負數(shù)處理
formula = negative_start_issue(formula)
# 2.雙加減符號處理
formula = deal_unusual_issue(formula)
# 3.加減邏輯運算
calc_list = re.split("[+-]", formula)
operator_list = re.findall("[+-]", formula)
res = 0
for index, i in enumerate(calc_list):
if index == 0:
res = float(i)
else:
if operator_list[index-1] == '+':
res += float(i)
elif operator_list[index-1] == '-':
res -= float(i)
return res
"""
四則混合運算主函數(shù)
"""def elementary_arithmetic(formula):
# 負數(shù)處理
formula = negative_start_issue(formula)
formula = deal_negative_issue(formula)
# 乘除運算
calc_list = re.split("[+-]",formula) # 通過+-符號將各個乘除運算分隔出來
calc_operator_list = re.findall("[+-]",formula)
for index1, item in enumerate(calc_list):
calc_list[index1] = str(multiply_divide(item)) #數(shù)據(jù)類型的強制轉(zhuǎn)換!??!
formula = update_formula(calc_list,calc_operator_list)
# 加減運算
formula = add_abstract(formula)
return formula
"""
括號運算
"""
def calculator(formula):
#數(shù)據(jù)預處理
formula = formula.replace(" ","")
m = re.search("\([^()]*\)",formula)
# 判斷是否需要進行括號運算
if m:
# 括號運算
# 提取最小括號運算式,計算結果,并返回。
subformula = m.group().strip("()") # 把找出來的括號剝離
print("subformula:",subformula,type(subformula))
subres = elementary_arithmetic(subformula) # 調(diào)用四則混合運算主函數(shù)
print("subres:",subres)
formula = formula.replace(m.group(), str(subres))
print("updated formula:",formula)
if "(" in formula:
return calculator(formula)
else:
print("formula result:",formula)
# 除去所有括號后可能出現(xiàn):1-2*-312.8
formula = elementary_arithmetic(formula)
return formula
else:
return elementary_arithmetic(formula)
# 以下為測試代碼:
formula = "1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*9/4*28 +10 * 56/14 )) - (-4*3)/ (16-3*2) )"
print("%s = "%formula,calculator(formula))
總結
以上所述是小編給大家介紹的Python利用正則表達式實現(xiàn)計算器算法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
使用Python中Tkinter模塊的Treeview?組件顯示ini文件操作
這篇文章主要介紹了使用Python中Tkinter模塊的Treeview組件顯示ini文件操作,Treeview組件位于ttk模塊,該模塊自Tk8.5開始引入,主題詳細介紹,需要的朋友可以參考一下2022-09-09

