思路:
用循环提取最里面的括号,再进行运算
运算时利用正则表达式寻找相应的运算符
先进行乘除,再进行加减
(参考武sir和金角大王的代码)
流程图:
代码:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import re 4 def cheng_and_chu(arg): #计算乘除 5 val = arg[0] #把传入的列表中第0个元素赋值给val 6 mch = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val) #利用正则表达式的查找字符串功能匹配val中的算数符赋值给mch 7 if not mch: #如果mch中没有乘除 8 return #结束函数返回这个mch中的值 9 content = re.search('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val).group() #利用正则表达式的查找字符串功能匹配val中的算数符,并使用group获取分组赋值给content 10 if len(content.split('*'))>1: #将content中的组以*分割,分割后的字符串长度大于1 11 n1,n2 = content.split('*') #将content中的组以*分割,分割后的两部分分别赋值给n1,n2 12 value = float(n1) * float(n2) #将n1,n2转换为浮点数,并相乘,结果赋值给value 13 else: 14 n1,n2 = content.split('/') 15 value = float(n1) / float(n2) 16 qianzhui,houzhui = re.split('\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*', val, 1) #用正则中的分割方法,吧val中的值以\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*分割,并将分割后的值分别赋值给qianzhi,后缀 17 new_str = "%s%s%s"%(qianzhui,value,houzhui) #将字符串重新格式化拼接 18 arg[0] = new_str #讲新的字符串复制给arg中的第0个元素 19 cheng_and_chu(arg) #继续运行乘除函数 20 21 def jia_and_jian(arg): #计算加减 22 while True: 23 if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__("--"): #如果arg的第0个元素是'+-','--','++','-+' 24 arg[0] = arg[0].replace('+-','-') #将-替换掉+- 25 arg[0] = arg[0].replace('++','+') #将+替换掉++ 26 arg[0] = arg[0].replace('-+','-') #将-替换掉-+ 27 arg[0] = arg[0].replace('--','+') #将+替换掉-- 28 else: 29 break 30 if arg[0].startswith('-'): #如果arg的第0个元素是以-开头 31 arg[1] += 1 #arg的第一个元素自加1 32 arg[0] = arg[0].replace('-','&') 33 arg[0] = arg[0].replace('+','-') 34 arg[0] = arg[0].replace('&','+')#将-变+,+变- 35 arg[0] = arg[0][1:]#将arg中第0个元素中前面多出来的符号去掉 36 val = arg[0] 37 mch = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val) 38 if not mch: 39 return 40 content = re.search('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val).group() 41 if len(content.split('+'))>1: 42 n1, n2 = content.split('+') 43 value = float(n1) + float(n2) 44 else: 45 n1, n2 = content.split('-') 46 value = float(n1) - float(n2) 47 before, after = re.split('\d+\.*\d*[\+\-]{1}\d+\.*\d*', val, 1) 48 new_str = "%s%s%s" % (before,value,after) 49 arg[0] = new_str 50 jia_and_jian(arg) 51 52 def jisuan(sr): #计算函数 53 new_sr = [sr.strip('()'),0] #将传入的值两边括号去掉,并组成列表赋值给new_sr 54 cheng_and_chu(new_sr) #调用乘除函数 55 jia_and_jian(new_sr) #调用加减函数 56 if divmod(new_sr[1],2)[1] == 1: #将运算后的传回的列表中的第1个元素处于2,除后得到的元组第1个元素等于1的话, 57 jieguo = float(new_sr[0]) #将运算后传回的列表中的第0个元素转化为浮点型,赋值给jieguo 58 jieguo = jieguo * -1 #并将jieguo乘-1 59 else: #如果不等于1 60 jieguo = float(new_sr[0]) #将运算后传回的列表中的第0个元素转化为浮点型,赋值给jieguo 61 return jieguo #结束函数返回jieguo 62 63 def kuohao(sr): #去除括号函数 64 flag = True #设置一个标志位 65 while flag: 66 m = re.search("\([^()]+\)",sr) #找出sr中最里面的括号,赋值给m 67 if m: 68 sub_sr = m.group() #截取m中第一个括号 69 sub_res = jisuan(sub_sr) #调用计算函数,返回值赋值给sub_res 70 sr = sr.replace(m.group(),str(sub_res)) #将m截取的第一个括号内容替换为转化为str类型的sub_res 71 else: 72 print('结果:',jisuan(sr)) #如果没有括号了,打印计算函数返回的结果 73 flag = False #将标志位设置为False,用于跳出循环 74 75 if __name__ == "__main__": 76 print("----------欢迎使用计算器----------") 77 while True: 78 flag = True #设置一个标志位 79 sr = input("输入要计算的函数(q:退出):") #让用户输入计算函数,赋值给sr 80 sr = re.sub("\s*","",sr) #在sr中找到所有的空格,删除 81 error = re.search('[0-9q\*\/\-\+]',sr) #使用正则查找方法,在sr中找到0-9q\*\/\-\+这些字符,赋值给error 82 while flag: 83 if not error: #如果error为空 84 print("输入有误") #打印输入有误 85 sr = input("请重新输入要计算的函数(q:退出):") #重新让用户输入 86 else: 87 if error.group() == 'q': #如果用户输入的是q 88 exit("感谢使用,再见") #则推出整个程序 89 kuohao(sr) #用户输入的是计算函数,则调用去除括号函数 90 flag = False #并将标志位设置为False