zoukankan      html  css  js  c++  java
  • 用python的正则表达式实现简单的计算器功能

    用python的正则表达式实现简单的计算器功能

     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import sys
    import re
     
    def welcome_func():
        """
        输入判断
        :param expression: 表达式
        :return: 返回有效表达式
        """
        welcome_str = "超级计算器"
        print(welcome_str.center(50,'*'),' ')  # 输出欢迎界面
        while True:
            iput = input("请输入你要计算的表达式[q:退出]:").strip()
            if iput == 'q':  # 退出计算
                sys.exit("bye-bye")
            elif len(iput) == 0:
                continue
            else:
                iput = re.sub('s*', '', iput)  # 去除空格
                return iput
     
    def chengchu(expression):
        """
        乘除运算
        :param expression: 表达式
        :return: 返回没有乘除的表达式/最终计算结果
        """
        val = re.search('d+.*d*[*/]+[+-]?d+.*d*', expression)  # 匹配乘除号
        if not val:  # 乘除号不存在,返回输入的表达式
            return expression
        data =  re.search('d+.*d*[*/]+[+-]?d+.*d*', expression).group()  # 匹配乘除号
        if len(data.split('*')) > 1:  # 当可以用乘号分割,证明有乘法运算
            part1, part2 = data.split('*')  # 以乘号作为分割符
            value = float(part1) * float(part2)  # 计算乘法
        else:
            part1, part2 = data.split('/')  # 用除号分割
            if float(part2) == 0:  # 如果分母为0,则退出计算
                sys.exit("计算过程中有被除数为0的存在,计算表达式失败!")
            value = float(part1) / float(part2)  # 计算除法
     
        #print("计算:%s=%s:" % (data,value) )
        # 获取第一个匹配到的乘除计算结果value,将value放回原表达式
        s1, s2 = re.split('d+.*d*[*/]+[+-]?d+.*d*', expression, 1)  # 分割表达式
        #print("上一个表达式:",expression)
        next_expression  = "%s%s%s" % (s1, value, s2)  # 将计算结果替换会表达式
        #print("下一个表达式%s" % next_expression)
        return chengchu(next_expression)  # 递归表达式
     
     
     
    def jiajian(expression):
        """
        加减运算
        :param expression: 表达式
        :return: 返回没有加减的表达式/最终计算结果
        """
        expression = expression.replace('+-','-')   # 替换表达式里的所有'+-'
        expression = expression.replace('--','+')   # 替换表达式里的所有'--'
        expression = expression.replace('-+','-')   # 替换表达式里的所有'-+'
        expression = expression.replace('++','+')   # 替换表达式里的所有'++'
        #print("处理特殊加减后的表达式:",expression)
        data = re.search('d+.*d*[+-]{1}d+.*d*', expression)   # 匹配加减号
        if not data:   # 如果不存在加减号,则证明表达式已计算完成,返回最终结果
            return expression
        val = re.search('[-]?d+.*d*[+-]{1}d+.*d*', expression).group()
        if len(val.split('+')) > 1:   # 以加号分割成功,有加法计算
            part1, part2 = val.split('+')
            value = float(part1) + float(part2)   # 计算加法
        elif val.startswith('-'):  # 如果是已'-'开头则需要单独计算
            part1, part2, part3  = val.split('-')
            value = -float(part2) - float(part3)  # 计算以负数开头的减法
        else:
            part1, part2 = val.split('-')
            value = float(part1) - float(part2)  # 计算减法
         
        s1, s2 =  re.split('[-]?d+.*d*[+-]{1}d+.*d*', expression, 1)  # 分割表达式
        #print("计算%s=%s" % (val,value))
        next_expression = "%s%s%s" % (s1, value, s2)   # 将计算后的结果替换回表达式,生成下一个表达式
        #print("下一个表达式: ",next_expression)
        return jiajian(next_expression)  # 递归运算表达式
     
     
    def del_bracket(expression):
        """
        小括号去除运算
        :param expression: 表达式
        :return:
        """
        if not re.search(r'(([^()]+))',expression):   # 判断小括号,如果不存在小括号,直接调用乘除,加减计算
            ret1 = chengchu(expression)
            ret2 = jiajian(ret1)
            return ret2   # 返回最终计算结果
        data = re.search(r'(([^()]+))', expression).group()  # 如果有小括号,匹配出优先级最高的小括号
        #print("获取表达式",data)
        data = data.strip('[()]')   # 剔除小括号
        ret1 = chengchu(data)   # 计算乘除
        #print("全部乘除计算完后的表达式:",ret1)
        ret2 = jiajian(ret1)   # 计算加减
        #print("全部加减计算结果:",ret2)
        part1, replace_str, part2 = re.split(r'(([^()]+))', expression, 1)  # 将小括号计算结果替换回表达式
        expression = '%s%s%s' % (part1, ret2, part2)  # 生成新的表达式
        return del_bracket(expression)  # 递归去小括号
         
     
    if __name__ == "__main__":
        try:
            expression = welcome_func()   # 获取到的表达式
            #expression = "-1+ 3 *(-3*2-2/-2+1)/2"
            #expression = '1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
            reslut = eval(expression)   # 用eval计算验证
            ret = del_bracket(expression)  # 用函数计算后得出的结果
            reslut = float(reslut)
            ret = float(ret)
            if reslut == ret:   # 将两种方式计算的结果进行比较,如果相等,则计算正确,输出结果
                print("eval计算结果:%s" % reslut)
                print("表达式计算结果:%s" % ret)
            else:   # 两种计算方式的结果不正确,提示异常,并返回两种方式的计算结果
                print("计算结果异常,请重新检查!")
                print("eval计算结果:%s" % reslut)
                print("表达式计算结果:%s" % ret)
        except(SyntaxError,ValueError,TypeError):   # 如果有不合法输出,则抛出错误
            print("输入表达式不合法,请重新检查!")

      

  • 相关阅读:
    797. 所有可能的路径
    1286. 字母组合迭代器
    216. 组合总和 III
    77. 组合
    784. 字母大小写全排列
    90. 子集 II
    78. 子集
    47. 全排列 II
    46. 全排列
    40. 组合总和 II
  • 原文地址:https://www.cnblogs.com/meng-wei-zhi/p/8259102.html
Copyright © 2011-2022 走看看