练习—计算器
一、要求
传入字符串,计算结果
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 string 11 12 #运算函数 13 def count(result): 14 result = plus_minus(result) #调用plus_minus函数,去除想叠的加减 15 if re.search('\d+\.?\d*[\+\-\*\/]\d+\.?\d*',result): #如果匹配到有+-*/,进入下面的if 16 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 result 44 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) #把函数返回的计算结果替换到string 54 print(cc) 55 else: #如果没有匹配到括号 56 return count(string) #直接把string传入count函数 57 return inin(cc) #把新的string字符串传入count 58 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_result 65 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 string 11 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): #如果匹配到有+-*/,进入下面的if 18 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 result 46 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 result 64 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) #把函数返回的计算结果替换到string 74 print(cc) 75 else: #如果没有匹配到括号 76 return count(string) #直接把string传入count函数 77 return inin(cc) #把新的string字符串传入count 78 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_result 85 print(string_result) #输出结果