zoukankan      html  css  js  c++  java
  • 用Python代码写的计算器

    1.极限压缩版

    import re, functools
    def cal(formula):
        while re.search('(?:d+.?d+|d+)[+-*/]', formula):
            while re.search('[*/]', formula): formula = re.sub('(?:d+.?d+|d+)[*/](?:d+.?d+|d+)', str(functools.reduce(lambda i, j: float(i) * float(j), re.search('(?:d+.?d+|d+)[*/](?:d+.?d+|d+)', formula).group().split('*')) if '*' in re.search('(?:d+.?d+|d+)[*/](?:d+.?d+|d+)', formula).group() else functools.reduce(lambda i, j: float(i) / float(j), re.search('(?:d+.?d+|d+)[*/](?:d+.?d+|d+)', formula).group().split('/'))), formula, 1)
            if re.search('(?:d+.?d+|d+)[+-]', formula): formula = re.sub('-?(?:d+.?d+|d+)[+-](?:d+.?d+|d+)', str(functools.reduce(lambda i, j: float(i) + float(j), re.search('-?(?:d+.?d+|d+)[+-](?:d+.?d+|d+)', formula).group().rsplit('+', 1)) if '+' in re.search('(?:d+.?d+|d+)[+-](?:d+.?d+|d+)', formula).group() else functools.reduce(lambda i, j: float(i) - float(j), re.search('-?(?:d+.?d+|d+)[+-](?:d+.?d+|d+)', formula).group().rsplit('-', 1))), formula, 1)
        return formula
    formula = '1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
    while re.search('([^()]+)', formula):
        formula = re.sub('([^()]+)', cal(re.search('([^()]+)', re.sub('s', '', formula)).group()).strip('()'), formula, 1)
        while re.search('[+-*/]-', formula): formula = re.sub('[+]-', '-', formula) if '+-' in formula else re.sub('--', '', formula) if formula.startswith('--') else re.sub('(?:d+.?d+|d+)[*/]-', '-' + re.findall('(?:d+.?d+|d+)[*/](?=-)', formula)[0], formula) if re.search('[*/]-', formula) else re.sub('--', '+', formula)
    print(cal(formula).split('.0')[0] if cal(formula).endswith('.0') else cal(formula))

    2.完整版

    import re
    from functools import reduce
    
    
    def plus_minus(formula):
        '''
        计算无括号的加减法算式
        :param formula: 等待计算的只包含加减法的字符串
        :return: 计算结果的字符串
        '''
        p1 = re.compile('-?(?:d+.?d+|d+)[+-](?:d+.?d+|d+)')  # 匹配一次加减法
        while re.search(p1, formula):  # 每次计算一个二元加减,并替换到原字符串上,直到计算并计算完所有数
            x = re.search(p1, formula).group()  # 匹配出一次计算,判断是加法还是减法,再由reduce把分割后的两个数交给匿名函数去计算。
            formula = re.sub(p1, str(reduce(lambda i, j: float(i) + float(j), x.rsplit('+', 1)) if '+' in x else reduce(lambda i, j: float(i) - float(j), x.rsplit('-', 1))), formula, 1)
        return formula
        # ps.计算加减法可以采用与乘除法不同的方式,可以把所有数全匹配出来再一起计算出来
    
    
    def multi_divi(formula):
        '''
        计算无括号的乘除法算式
        :param formula: 等待计算的只包含乘除法的字符串
        :return: 计算结果的字符串
        '''
        p = re.compile('(?:d+.?d+|d+)[*/](?:d+.?d+|d+)')
        while re.search(p, formula):
            y = re.search(p, formula).group()
            formula = re.sub(p, str(reduce(lambda i, j: float(i) * float(j), y.split('*')) if '*' in y else reduce(lambda i, j: float(i) / float(j), y.split('/'))), formula, 1)
        return formula
    
    
    def parentheses_parse(formula):
        '''
        用来处理括号,并调用加减乘除完成计算
        :param formula: 数学算式的字符串,支持加减乘除和括号
        :return: 最终结果的整型或浮点型
        '''
        formula = re.sub('s', '', formula)
        p = re.compile('([^()]+)')  # 匹配内层括号
        while re.search(p, formula):  # 循环到没有括号为止
            f = re.search(p, formula).group()
            formula = re.sub(p, plus_minus(multi_divi(f)).strip('()'), formula, 1)  # 调用加减法嵌套乘除法,计算完括号内的式子,并去除括号
    
            # 处理去除括号后可能出现的其他符号与负号相连的情况
            while re.search('[+-*/]-', formula):
                formula = re.sub('[+]-', '-', formula)
                formula = re.sub('--', '', formula) if formula.startswith('--') else re.sub('--', '+', formula)  # 正负为负,负负为正,并且避免正号出现在最前端
                if re.search('[*/]-', formula):  # 遇到乘除连接负号的情况时,需要先把负号前置,再进行一次上面加减连接负号的处理
                    n = re.search('(?:d+.?d+|d+)[*/](?=-)', formula).group()  # 这里使用正向预匹配获得如'7*-'这样的序列中的'7*'的部分
                    formula = re.sub('(?:d+.?d+|d+)[*/]-', '-' + n, formula)  # 使用刚获得的字符串进行替换,来使‘7*-’变成‘-7*’的样子
        formula = plus_minus(multi_divi(formula))  # 没有括号了,再计算最后一次
        if formula.endswith('.0'):  # 优化显示
            formula = int(formula.split('.0')[0])
        else:
            formula = float(formula)
        return formula
    
    
    # 在此处输入算式
    print(parentheses_parse('1-2*((60-  30+(-40/5)*(9  -2*5/3+7/3*99/4*2998+1  0*568/14))-(-4*3)/(16-3*2))'))

    3.思路清晰版

    import re
    from functools import reduce
    
    def mul_div(exp):
        """
        计算两个数的乘法或者除法
        :param exp:
        :return:
        """
        if '*' in exp:
            a, b = exp.split('*')
            return float(a)*float(b)
        if '/' in exp:
            a, b = exp.split('/')
            return float(a) / float(b)
    
    def exp_fmt(exp):
        """
        符号整理
        :param exp:
        :return:
        """
        while re.search('[+-]{2,}',exp):
            exp = exp.replace('--','+')
            exp = exp.replace('+-','-')
            exp = exp.replace('-+','-')
            exp = exp.replace('++','+')
        return exp
    
    def remove_addsub(exp):
        """
        计算两个数的加减法
        :param exp:
        :return:
        """
        ret = re.findall('[-+]?d+(?:.d+)?',exp)
        res = reduce(lambda a,b:float(a)+float(b),ret)
        return res
    
    def remove_muldiv(exp):
        """
        计算表达式中的所有的乘除法
        :param exp:
        :return:
        """
        while True:
            ret = re.search('d+(.d+)?[*/]-?d+(.d+)?',exp)
            if ret:
                son_exp = ret.group()
                res = mul_div(son_exp)
                exp = exp.replace(son_exp,str(res))
            else:return exp
    
    def cal(exp):
        res = remove_muldiv(exp)            # 计算乘除
        res = exp_fmt(res)                  # 符号整理
        ret = remove_addsub(res)            # 计算加减
        return ret
    
    def main(exp):
        exp = exp.replace(' ','')
        while True:
            ret = re.search('([^()]+)', exp)
            if ret:
                res = cal(ret.group())
                exp = exp.replace(ret.group(), str(res))
            else: return cal(exp)
    exp = '1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )'
    ret = main(exp)
    print(ret)

    待续

  • 相关阅读:
    程序的了解
    Oracle VM VirtualBox虚拟网卡消失解决方法
    YARN 运维、巡检、监控、调优、排障
    HDFS巡检、监控、调优、排障
    Windows CMD命令大全
    [HDU]6356 Glad You Came(ST表)
    [BZOJ] 1019 [SHOI2008]汉诺塔
    树上叶子之间点对距离平方和
    [BZOJ]1026[SCOI2009]windy数
    [计蒜客]A1542 The Maximum Unreachable Node Set
  • 原文地址:https://www.cnblogs.com/zangyue/p/12056160.html
Copyright © 2011-2022 走看看