读藤兰老师的代码有一小段没太懂,也并不知道存在的意义,对代码稍作了一些改动,在eval中是支持类似((3*4))这种括号重复嵌套的,故加了一段来处理重复括号的,博主使用的3.x。
1 patter = '\(([\+\-]*\d+\.*\d*)\)' 2 if re.search(patter, expression) : 3 content = re.search(patter, expression).group() 4 before, nothing, after = re.split(patter, expression, 1) 5 content = content[1:len(content)-1] 6 expression = "%s%s%s" %(before, content, after)
1 #!/usr/bin/env python
2 # -*- coding:utf-8 -*-
3 """
4 该计算器思路:
5 1、递归寻找表达式中只含有 数字和运算符的表达式,并计算结果
6 2、由于整数计算会忽略小数,所有的数字都认为是浮点型操作,以此来保留小数
7 使用技术:
8 1、正则表达式
9 2、递归
10 """
11 import re
12
13
14 def compute_mul_div(arg):
15 """ 操作乘除
16 :param expression:表达式
17 :return:计算结果
18 """
19 val = arg[0]
20 patter = '\d+\.*\d*[\*\/]+[\+\-]?\d+\.*\d*'
21 mch = re.search(patter, val)
22 if not mch:
23 return
24 content = re.search(patter, val).group()
25
26 if len(content.split('*'))>1:
27 n1, n2 = content.split('*')
28 value = float(n1) * float(n2)
29 else:
30 n1, n2 = content.split('/')
31 value = float(n1) / float(n2)
32
33 before, after = re.split(patter, val, 1)
34 new_str = "%s%s%s" % (before,value,after)
35 arg[0] = new_str
36 compute_mul_div(arg)
37
38 def compute_add_sub(arg):
39 """ 操作加减
40 :param expression:表达式
41 :return:计算结果
42 """
43 while True:
44 if arg[0].__contains__('+-') or arg[0].__contains__("++") or arg[0].__contains__('-+') or arg[0].__contains__("--"):
45 arg[0] = arg[0].replace('+-','-')
46 arg[0] = arg[0].replace('++','+')
47 arg[0] = arg[0].replace('-+','-')
48 arg[0] = arg[0].replace('--','+')
49 else:
50 break
51 val = arg[0]
52 patter = '\d+\.*\d*[\+\-]{1}\d+\.*\d*'
53 mch = re.search(patter, val)
54 if not mch:
55 return
56 content = re.search(patter, val).group()
57 if len(content.split('+'))>1:
58 n1, n2 = content.split('+')
59 value = float(n1) + float(n2)
60 else:
61 n1, n2 = content.split('-')
62 value = float(n1) - float(n2)
63
64 before, after = re.split(patter, val, 1)
65 new_str = "%s%s%s" % (before,value,after)
66 arg[0] = new_str
67 compute_add_sub(arg)
68
69 def compute(expression):
70 """ 操作加减乘除
71 :param expression:表达式
72 :return:计算结果
73 """
74 inp = [expression]
75 # 处理表达式中的乘除
76 compute_mul_div(inp)
77 # 处理
78 compute_add_sub(inp)
79 result = float(inp[0])
80 return result
81
82 def exec_bracket(expression):
83 """ 递归处理括号,并计算
84 :param expression: 表达式
85 :return:最终计算结果
86 """
87 patter = '\(([\+\-]*\d+\.*\d*)\)'
88 if re.search(patter, expression) :
89 content = re.search(patter, expression).group()
90 before, nothing, after = re.split(patter, expression, 1)
91 content = content[1:len(content)-1]
92 expression = "%s%s%s" %(before, content, after)
93
94 patter = '\(([\+\-\*\/]*\d+\.*\d*){2,}\)'
95 if not re.search(patter, expression):
96 final = compute(expression)
97 return final
98 content = re.search(patter, expression).group()
99 before, nothing, after = re.split(patter, expression, 1)
100 print ('before:',expression)
101 content = content[1:len(content)-1]
102 ret = compute(content)
103 print ('%s=%s' %( content, ret))
104 expression = "%s%s%s" %(before, ret, after)
105 print ('after:',expression)
106 print ("="*10,'上一次计算结束',"="*10)
107 return exec_bracket(expression)
108
109 if __name__ == "__main__":
110 inpp = '1 - 2 * ( ( (-60-30 +(-40.0+5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) ) - (-4*3)/ (16-3*2) ) '
111 # inpp = "1-2*-30/-12*(-20+200*-3/-200*-300-100)"
112 # inpp = "1-5*980.0"
113 # inpp = '(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )'
114 # inpp = '-50-10'
115 inpp = re.sub('\s*','',inpp)
116 # inpp = inpp.replace(' ','')
117 result = exec_bracket(inpp)
118 print (result)
小弟今天自己写了下,又发现了个问题,上面的是不能正确计算-5-4这样的算式的,直接上代码吧
1 """
2 递归实现简单的计算器
3 思路来源 武藤兰
4 由正则表达式找去最内层括号
5 进行基本的加减乘除运算
6 加减法要 特殊处理 ++ +- -+ --
7 """
8 import re
9 class Calculation(object):
10 """docstring for Calculation"""
11 def __init__(self, arg):
12 super(Calculation, self).__init__()
13 self.arg = arg
14
15 def operator(self, arg):
16 expression = arg[0]
17 # print ('operator')
18 patter = '(\+\+)|(\-\-)'
19 contect = re.search(patter, expression)
20 if contect:
21 # print (re.split(patter, expression, 1))
22 before, nothinga, nothingb, after = re.split(patter, expression, 1)
23 arg[0] = '%s%s%s'%(before,'+',after)
24 patter = '(\-\+)|(\+\-)'
25 contect = re.search(patter, expression)
26 if contect:
27 before, nothinga, nothingb, after = re.split(patter, expression, 1)
28 arg[0] = '%s%s%s'%(before,'-',after)
29
30 def add(self, arg):
31 # print (arg)
32 content = arg[0]
33 if len(content.split('+'))>1:
34 n1, n2 = content.split('+')
35 n1 = arg[1]+n1
36 value = float(n1) + float(n2)
37 elif len(content.split('-'))>1:
38 n1, n2 = content.split('-')
39 n1 = arg[1]+n1
40 value = float(n1) - float(n2)
41 else:
42 value = float(arg[1]+arg[0])
43 return value
44
45
46 def add_subtract(self, arg):
47 self.operator(arg)
48 expression = arg[0]
49 # print (expression, 'add_subtract')
50 patter = '([\+\-]*\d+\.*\d*[\+\-]+\d+\.*\d*)'
51 contect = re.search(patter, expression)
52 if contect:
53 contect = contect.group()
54 # print (contect,'contect')
55 if contect[0] == '+':
56 value = self.add([contect[1:len(contect)],'+'])
57 elif contect[0] == '-':
58 value = self.add([contect[1:len(contect)],'-'])
59 else:
60 value = self.add([contect[0:len(contect)],''])
61 else:
62 return
63 before, nothing, after = re.split(patter, expression, 1)
64 new_str = "%s%s%s" % (before,value,after)
65 arg[0] = new_str
66 self.add_subtract(arg)
67
68 def multiply_divide(self, arg):
69 self.operator(arg)
70 expression = arg[0]
71 # print (expression, 'multiply_divide')
72 patter = '(\d+\.*\d*[\*\/]+[\-]*\d+\.*\d*)'
73 contect = re.search(patter, expression)
74 if contect:
75 contect = contect.group()
76 if len(contect.split('*'))>1:
77 n1,n2=contect.split('*')
78 value = float(n1)*float(n2)
79 else:
80 n1,n2=contect.split('/')
81 value = float(n1)/float(n2)
82 else:
83 return
84 before, nothing, after = re.split(patter, expression, 1)
85 new_str = "%s%s%s" % (before,value,after)
86 arg[0] = new_str
87 self.multiply_divide(arg)
88
89 def computing(self, arg):
90 self.multiply_divide(arg)
91 self.add_subtract(arg)
92 return float(arg[0])
93
94 def remove_brackets(self, arg):
95 expression = arg.replace(' ','')
96 patter = '\([^()]+\)'
97 # patter = '\(([\+\-\*\/]*\d+\.*\d*){2,}\)'
98 contect = re.search(patter, expression)
99 if contect:
100 contect = contect.group()
101 before, after = re.split(patter, expression, 1)
102 contect = contect.strip('()')
103 value = self.computing([contect])
104 print (contect, '=', value)
105 expression = '%s%s%s'%(before, value, after)
106 print (expression,'new expression')
107 print ('*'*10, 'next', '*'*10,)
108 self.remove_brackets(expression)
109 else:
110 print (self.computing([expression]))
111
112 if __name__ == '__main__':
113 inpp = '1 - 2 * ( ( (60-30 +((-40.0-5)) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) ) - (-4*3)/ (16-3*2) ) '
114 ca = Calculation(inpp)
115 ca.remove_brackets(inpp)
116 print (eval(inpp), 'eval')
转自作者:武沛齐
出处:
http://www.cnblogs.com/wupeiqi/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
