思路:
用循环提取最里面的括号,再进行运算
运算时利用正则表达式寻找相应的运算符
先进行乘除,再进行加减
(参考武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