zoukankan      html  css  js  c++  java
  • 简单版计算器

    解题思路

        一、计算器运算规则

                优先级                    匹配格式

        1. 小括号(最底层的)                    括号里没有括号

               小括号里算式计算优先级:

                         2.幂运算            (正数)**(正数)、(正数)**(负数)     ---支持小数

                         3.乘除                (正数或负数)(*/)(正数或负数)         ---支持小数

                         4.加减                (正数或负数)(+-)(正数或负数)         ---支持小数

        二、运算流程

        1.search匹配第一个最底层的括号

        2.通过match对象的groups方法获取括号里算式

        3.对括号内的算式进行幂运算匹配

        4.调用幂运算函数对匹配到的对象进行处理

        5.用sub将结果替换括号内算式的匹配到的对象

        6.重复3、4、5,直到没有匹配对象

        7.对替换的算式进行乘除运算匹配

        8.调用乘除运算函数对匹配到的对象进行处理

        9.用sub将结果替换括号内算式的匹配到的对象

        10.重复7、8、9直到没有匹配对象

        11.对替换的算式进行加减运算匹配

        12.调用加减运算函数对匹配到的对象进行处理

        13.用sub将结果替换括号内算式的匹配到的对象

        14.重复11、12、13直到没有匹配对象

        15、重复上述步骤,直到没有括号

        16.得到没有括号的算式后,只要再按照幂、乘除、加减步骤走

        17.得到结果

    流程图

      我还发现python在处理运算时,会自动帮我们处理正负号,所以在匹配时不用太多的去关心数字前的正负号

            

    代码实现

    #题目:求得字符串里'1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'计算式的结果
    
    
    import re
    
    #匹配规则
    brackets = re.compile('(([^()]+))')
    powers = re.compile('(d+.?d*)**(-?d+.?d*)')
    mul_div = re.compile('(-?d+.?d*)([*/])(-?d+.?d*)')
    add_cut = re.compile('(-?d+.?d*)([+-])(-?d+.?d*)')
    
    def powers_calculate(match_obj):
        '''
        处理幂运算
        :param match_obj: 需要处理的match对象
        :return:算式的结果
        '''
        mat_grs = match_obj.groups()
        n1 = float(mat_grs[0])
        n2 = float(mat_grs[1])
        return n1**n2
    
    def mul_div_calculate(match_obj):
        '''
        处理乘除运算
        :param match_obj: 需要处理的match对象
        :return: 算式的结果
        '''
        mat_grs = match_obj.groups()
        n1 = float(mat_grs[0])
        n2 = float(mat_grs[2])
        if mat_grs[1] == '*':
            return n1*n2
        else:
            return n1/n2
    
    def add_cut_calculate(match_obj):
        '''
        处理加减运算
        :param match_obj: 需要处理的match对象
        :return: 算式的结果
        '''
        mat_grs = match_obj.groups()
        n1 = float(mat_grs[0])
        n2 = float(mat_grs[2])
        if mat_grs[1] == '+':
            return n1+n2
        else:
            return n1-n2
    
    
    #数据源
    data_sour = '1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
    
    # data_sour = input('请输入你要计算的算式:')
    #==================================================================================
    
    #匹配最底层的括号
    brackets_match = brackets.search(data_sour)
    
    #对匹配到的括号进行处理
    while True:
        if brackets_match:                  #判断匹配成功与否
            print(brackets_match.group())   #(9-2*5/3+7/3*99/4*2998+10*568/14)
            mat_groups1 = brackets_match.groups()  #得到去括号的组的值,不过此时这里是元组
            print(mat_groups1)              #('9-2*5/3+7/3*99/4*2998+10*568/14',)
    
            #处理幂运算
            text = mat_groups1[0]      #得到最底层括号里的算式字符串
            powers_match = powers.search(text)  #匹配幂运算
            while True:
                if powers_match:                #判断匹配成功与否
                    print(powers_match.group())
                    ret1 = powers_calculate(powers_match) #调用幂运算函数
                    print(ret1)
                    text = re.sub(powers,str(ret1),text,1)  #把得到的幂运算结果替换匹配到的字符串
                    powers_match = powers.search(text)      #对替换的字符串再次进行幂运算匹配
                else:
                    break                        #匹配失败,就退出匹配幂运算的循环
    
            #处理乘除运算
            mul_div_match = mul_div.search(text)  #对处理幂运算后的字符串进行乘除运算匹配
            while True:
                if mul_div_match:                 #判断匹配成功与否
                    print(mul_div_match.group())
                    ret2 = mul_div_calculate(mul_div_match)  #调用乘除运算函数
                    print(ret2)
                    text = re.sub(mul_div,str(ret2),text,1)  #把得到的乘除运算结果替换匹配的字符串
                    print(text)
                    mul_div_match = mul_div.search(text)     #对处理后的字符串再进行乘除运算匹配
                else:
                    break   #匹配失败,就退出匹配乘除运算的循环
    
            #处理加减运算
            add_cut_match = add_cut.search(text)    #对处理乘除后的字符串进行加减运算匹配
            while True:
                if add_cut_match:                   #判断匹配成功与否
                    print(add_cut_match.group())
                    ret3 = add_cut_calculate(add_cut_match)  #调用加减运算函数
                    text = re.sub(add_cut,str(ret3),text,1)  #用得到的加减运算结果替换匹配的字符串
                    print(text)
                    add_cut_match = add_cut.search(text)  #对处理后的字符串再进行加减运算匹配
                else:
                    break      #匹配失败,退出匹配加减运算的循环
    
            data_sour = re.sub(brackets,text,data_sour,1)  #把括号里的计算结果替换匹配的括号
            brackets_match = brackets.search(data_sour)   #再次对处理后字符串进行括号的匹配
    
        else:
            break     #匹配不到括号,就退出匹配括号的循环
    
    #对处理括号完后的算式进行最后的运算
    #幂
    powers_match = powers.search(data_sour)
    while True:
        if powers_match:
            ret1 = powers_calculate(powers_match)
            data_sour = re.sub(powers,str(ret1),data_sour,1)
            powers_match = powers.search(data_sour)
        else:
            break
    
    #乘除
    mul_div_match = mul_div.search(data_sour)
    while True:
        if mul_div_match:
            ret1 = mul_div_calculate(mul_div_match)
            data_sour = re.sub(mul_div, str(ret1), data_sour, 1)
            mul_div_match = mul_div.search(data_sour)
        else:
            break
    
    #加减
    add_cut_match = add_cut.search(data_sour)
    while True:
        if add_cut_match:
            ret1 = add_cut_calculate(add_cut_match)
            data_sour = re.sub(add_cut, str(ret1), data_sour, 1)
            add_cut_match = add_cut.search(data_sour)
        else:
            break
    
    print('最后结果为:',data_sour)
    
    #验证结果
    data_sour = '1-2*((60-30+9*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
    jieguo = eval(data_sour)
    print('验证结果:',jieguo)
    
  • 相关阅读:
    Python中的装饰器之@wraps(四)
    python中装饰器之有参装饰器(三)
    python中装饰器之叠加装饰器(二)
    python中装饰器之闭包函数(一)
    python中的命名空间
    函数的嵌套与迭代
    函数对象
    matlab学习checkbox使用
    matlab学习滚动条改变文本数值
    matlab学习GUI可调的界面窗口
  • 原文地址:https://www.cnblogs.com/xinsiwei18/p/5912163.html
Copyright © 2011-2022 走看看