计算器基础实现
读藤兰老师的代码有一小段没太懂,也并不知道存在的意义,对代码稍作了一些改动,在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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。