Python利用正则表达式实现计算器算法思路解析
(1)不使用eval()等系统自带的计算方法
(2)实现四则混合运算、括号优先级解析
思路:
1、字符串预处理,将所有空格去除
2、判断是否存在括号运算,若存在进行第3步,若不存在则直接进入第4步
3、利用正则表达式获取最底层括号内的四则运算表达式
4、将四则运算表达式进行预处理:表达式开头有负数时,在表达式前加上一个0
5、利用re.split()、re.findall()方法,通过加减符号,对四则运算进行拆分为乘除运算式和数字,并保留对应的位置下标。
6、利用re.split()、re.findall()方法,通过乘除符号,将乘除式拆分为乘除符号与数字,然后进行计算,并返回数值。
7、通过re.split()、re.findall()保留的下标位置,将表达式还原。
8、完成所有乘除运算之后,返回进行加减运算。
9、完成加减运算后,返回表达式进行替代。
10、通过递归函数,完成所有括号运算后。最后再完成一次四则运算即可完成所有运算。
注:在过程中,负数的处理存在三个要点:当负数出现在表达式开头、负数前面存在减法、乘除式中存在负数且不在表达式开头。
(1)当负数出现在表达式开头:在前面加上一个0
(2)负数前面存在减法:每次完成一次运算后需要进行一次符号检查替换
(3)乘除式中存在负数且不在表达式开头:将负号移到表达式最开头
#!/usr/bin/envpython
#-*-coding:utf-8-*-
#Author:Dang
importre
defupdate_formula(calc_list,calc_operator_list):
#通过拆分后的表达式列表与符号列表重新组合
forindex,iteminenumerate(calc_list):
ifindex==0:
formula=item
elifindex!=0:
formula+=calc_operator_list[index-1]+item
returnformula
defnegative_start_issue(formula):
#处理负数在括号内表达式开头的情形
calc_list=re.split("[+-]",formula)#通过+-符号将各个乘除运算分隔出来
calc_operator_list=re.findall("[+-]",formula)
forindex,iteminenumerate(calc_list):
ifindex==0anditem=='':#处理负号在开头的问题
calc_list[index]='0'
else:
calc_list[index]=item.strip()
formula=update_formula(calc_list,calc_operator_list)
returnformula
defdeal_unusual_issue(formula):
#双加减符号处理
formula=formula.replace("","")#去掉空格
formula=formula.replace("++","+")
formula=formula.replace("+-","-")
formula=formula.replace("-+","-")
formula=formula.replace("--","+")
returnformula
defdeal_negative_issue(formula):
#处理乘除运算中负数的计算问题(分前后位置两种情况)
#1.负数在后
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]+"误把非必要项当做必要项。
ifm:
minus_pre=m.group()
minus_pro="-"+minus_pre.replace("-","")
formula=formula.replace(minus_pre,minus_pro)
if"*-"informulaor"/-"informula:
returndeal_negative_issue(formula)
#2.负数在前
formula=deal_unusual_issue(formula)
returnformula
defmultiply_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
forindex2,iinenumerate(calc_list):
ifindex2==0:
res=float(i)
else:
ifoperator_list[index2-1]=='*':#通过sub_operator_list中的index判断到底是加法还是减法,
res*=float(i)
elifoperator_list[index2-1]=='/':
res/=float(i)
returnres
defadd_abstract(formula):
#加减计算
#1.开头位置负数处理
formula=negative_start_issue(formula)
#2.双加减符号处理
formula=deal_unusual_issue(formula)
#3.加减逻辑运算
calc_list=re.split("[+-]",formula)
operator_list=re.findall("[+-]",formula)
res=0
forindex,iinenumerate(calc_list):
ifindex==0:
res=float(i)
else:
ifoperator_list[index-1]=='+':
res+=float(i)
elifoperator_list[index-1]=='-':
res-=float(i)
returnres
"""
四则混合运算主函数
"""defelementary_arithmetic(formula):
#负数处理
formula=negative_start_issue(formula)
formula=deal_negative_issue(formula)
#乘除运算
calc_list=re.split("[+-]",formula)#通过+-符号将各个乘除运算分隔出来
calc_operator_list=re.findall("[+-]",formula)
forindex1,iteminenumerate(calc_list):
calc_list[index1]=str(multiply_divide(item))#数据类型的强制转换!!!
formula=update_formula(calc_list,calc_operator_list)
#加减运算
formula=add_abstract(formula)
returnformula
"""
括号运算
"""
defcalculator(formula):
#数据预处理
formula=formula.replace("","")
m=re.search("\([^()]*\)",formula)
#判断是否需要进行括号运算
ifm:
#括号运算
#提取最小括号运算式,计算结果,并返回。
subformula=m.group().strip("()")#把找出来的括号剥离
print("subformula:",subformula,type(subformula))
subres=elementary_arithmetic(subformula)#调用四则混合运算主函数
print("subres:",subres)
formula=formula.replace(m.group(),str(subres))
print("updatedformula:",formula)
if"("informula:
returncalculator(formula)
else:
print("formularesult:",formula)
#除去所有括号后可能出现:1-2*-312.8
formula=elementary_arithmetic(formula)
returnformula
else:
returnelementary_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利用正则表达式实现计算器算法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!