一、要求
传入字符串,计算结果
string='1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
二、实现思路
1、先去除字符串内的空格。
2、然后按照括号优先的规则先用正则找出最里层的括号。
3、去除括号后把括号里的内容传入计算的函数。
4、在计算函数内用递归对传入的内容按照先乘除后加减的顺序进行计算和替换,直到得到一个数字。
5、最后把计算的结果返回赋值并对整个字符串进行替换。
6、在把新的字符串传入进行寻找括号的计算。
7、如果已经没有括号了就直接把该字符串传入计算。
8、直到最后如果已经找不到加减乘除这些计算符号,得到的就是最后的结果。
三、流程图
四、实现
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import re 4 #当加减相叠时使其转换成一个 5 def plus_minus(string): 6 string = string.replace('++','+') 7 string = string.replace('--','+') 8 string = string.replace('-+','-') 9 string = string.replace('+-','-')10 return string11 12 #运算函数13 def count(result):14 result = plus_minus(result) #调用plus_minus函数,去除想叠的加减15 if re.search('\d+\.?\d*[\+\-\*\/]\d+\.?\d*',result): #如果匹配到有+-*/,进入下面的if16 if re.search("[\/\*]",result): #先判断是否有乘除,有则先进入计算乘除17 #该正则意思为匹配:两个相乘或相除的整数或浮点数18 ss=re.search('(\d+\.?\d*)[\*\/]([\+\-]*\d+\.?\d*)',result).group()19 if re.search("\*",ss): #如果匹配的是相乘20 a=re.split("\*",ss) #以*分隔开21 a1=float(a[0])*float(a[1]) #取出两个数相乘22 result=result.replace(ss,str(a1)) #把计算好的结果替换到result里23 return count(result) #把新的result传入count函数继续计算24 if re.search("\/",ss): #如果匹配的是相除25 a=re.split("\/",ss) #以/分隔开26 a1=float(a[0])/float(a[1]) #取出两个数相除27 result=result.replace(ss,str(a1)) #同上28 return count(result)29 else: #如果没有匹配到乘除,则进入计算加减30 if re.search("[\+\-]",result): #先判断是否有加减31 ss=re.search('(\d+\.?\d*)[\+\-]([\+\-]*\d+\.?\d*)',result).group()32 if re.search("\+",ss): #如果匹配的是相加33 a=re.split("\+",ss) #以+分隔开34 a1=float(a[0])+float(a[1]) #取出两个数相加35 result=result.replace(ss,str(a1)) #把计算好的结果替换到result里36 return count(result)37 if re.search("\-",ss): #如果匹配的是相减38 a=re.split("\-",ss) #以-分隔开39 a1=float(a[0])-float(a[1]) #取出两个数相减40 result=result.replace(ss,str(a1)) #同上41 return count(result)42 else:43 return result44 45 #取值替换46 def inin(string):47 string = plus_minus(string)48 if re.search('\(([\+\-\*\/]*\d+\.*\d*)+\)',string): #如果该字符串能匹配括号49 result=re.search('\(([\+\-\*\/]*\d+\.*\d*)+\)',string).group() #取出最里面的括号50 print(result)51 result1=result.strip("\(\)") #除去括号52 aa=count(result1) #把除去括号的结果传入count函数53 cc=string.replace(result,aa) #把函数返回的计算结果替换到string54 print(cc)55 else: #如果没有匹配到括号56 return count(string) #直接把string传入count函数57 return inin(cc) #把新的string字符串传入count58 59 #程序开始60 if __name__ == '__main__':61 print('1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )')62 string=input("请输入表达式:")63 string = re.sub('\s*','',string) #除空格64 string_result=inin(string) #把string传入inin函数,并把返回的结果赋值给string_result65 print(string_result) #输出结果
改进版,加了**和//
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import re 4 #当加减相叠时使其转换成一个 5 def plus_minus(string): 6 string = string.replace('++','+') 7 string = string.replace('--','+') 8 string = string.replace('-+','-') 9 string = string.replace('+-','-')10 return string11 12 #加减乘除运算函数13 def count(result):14 result = plus_minus(result) #调用plus_minus函数,去除想叠的加减15 16 result=count_add(result) #运算幂次等其他算法17 if re.search('\d+\.?\d*[\+\-\*\/]\d+\.?\d*',result): #如果匹配到有+-*/,进入下面的if18 if re.search("[\/\*]",result): #先判断是否有乘除,有则先进入计算乘除19 #该正则意思为匹配:两个相乘或相除的整数或浮点数20 ss=re.search('(\d+\.?\d*)[\*\/]([\+\-]*\d+\.?\d*)',result).group()21 if re.search("\*",ss): #如果匹配的是相乘22 a=re.split("\*",ss) #以*分隔开23 a1=float(a[0])*float(a[1]) #取出两个数相乘24 result=result.replace(ss,str(a1)) #把计算好的结果替换到result里25 return count(result) #把新的result传入count函数继续计算26 if re.search("\/",ss): #如果匹配的是相除27 a=re.split("\/",ss) #以/分隔开28 a1=float(a[0])/float(a[1]) #取出两个数相除29 result=result.replace(ss,str(a1)) #同上30 return count(result)31 else: #如果没有匹配到乘除,则进入计算加减32 if re.search("[\+\-]",result): #先判断是否有加减33 ss=re.search('(\d+\.?\d*)[\+\-]([\+\-]*\d+\.?\d*)',result).group()34 if re.search("\+",ss): #如果匹配的是相加35 a=re.split("\+",ss) #以+分隔开36 a1=float(a[0])+float(a[1]) #取出两个数相加37 result=result.replace(ss,str(a1)) #把计算好的结果替换到result里38 return count(result)39 if re.search("\-",ss): #如果匹配的是相减40 a=re.split("\-",ss) #以-分隔开41 a1=float(a[0])-float(a[1]) #取出两个数相减42 result=result.replace(ss,str(a1)) #同上43 return count(result)44 else:45 return result46 47 def count_add(result):48 result = plus_minus(result)49 if re.search('\d+\.?\d*\*\*\d+\.?\d*',result) or re.search('\d+\.?\d*\/\/\d+\.?\d*',result):50 if re.search('\d+\.?\d*\*\*\d+\.?\d*',result):51 ss=re.search('\d+\.?\d*\*\*\d+\.?\d*',result).group()52 a=re.split("\*\*",ss)53 a1=float(a[0])**float(a[1])54 result=result.replace(ss,str(a1))55 return count_add(result)56 if re.search('\d+\.?\d*\/\/\d+\.?\d*',result):57 ss=re.search('\d+\.?\d*\/\/\d+\.?\d*',result).group()58 a=re.split("\/\/",ss)59 a1=float(a[0])//float(a[1])60 result=result.replace(ss,str(a1))61 return count_add(result)62 else:63 return result64 65 #取值替换66 def inin(string):67 string = plus_minus(string)68 if re.search('\(([\+\-\*\/]*\d+\.*\d*)+\)',string): #如果该字符串能匹配括号69 result=re.search('\(([\+\-\*\/]*\d+\.*\d*)+\)',string).group() #取出最里面的括号70 print(result)71 result1=result.strip("\(\)") #除去括号72 aa=count(result1) #把除去括号的结果传入count函数,运算加减乘除73 cc=string.replace(result,aa) #把函数返回的计算结果替换到string74 print(cc)75 else: #如果没有匹配到括号76 return count(string) #直接把string传入count函数77 return inin(cc) #把新的string字符串传入count78 79 #程序开始80 if __name__ == '__main__':81 print('1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )')82 string=input("请输入表达式:")83 string = re.sub('\s*','',string) #除空格84 string_result=inin(string) #把string传入inin函数,并把返回的结果赋值给string_result85 print(string_result) #输出结果