zoukankan      html  css  js  c++  java
  • 计算器基础实现

     读藤兰老师的代码有一小段没太懂,也并不知道存在的意义,对代码稍作了一些改动,在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/ 
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    iOS 版本更新迭代
    iOS 去掉导航栏最下面线的方法
    iOS AFNetWorking中block执行完后再执行其它操作
    iOS UICollectionViewCell 的拖动
    iOS 开发中有关pch文件,以及pch常用的内容
    iOS 中UIWebView的cookie
    iOS有关通讯录操作
    Eclipse 快捷键
    SublimeText
    正则表达式
  • 原文地址:https://www.cnblogs.com/whitehorse/p/5861679.html
Copyright © 2011-2022 走看看