计算器基础实现

 读藤兰老师的代码有一小段没太懂,也并不知道存在的意义,对代码稍作了一些改动,在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)
'\(([\+\-\*\/]*\d+\.*\d*){2,}\)' 去除括号的正则,这样是可以匹配到(*9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 ))的表达式,我改成'\(([\+\-]*\d+\.*\d*)([\+\-\*\/]*\d+\.*\d*)+\) 试了下,还是会有问题。
  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)
View Code

小弟今天自己写了下,又发现了个问题,上面的是不能正确计算-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')
View Code

转自作者:武沛齐 

出处:http://www.cnblogs.com/wupeiqi/ 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
原文地址:https://www.cnblogs.com/whitehorse/p/5861679.html