• 计算器实例


    计算器实例

    一、文字思路分析

    拿到一个表达式,例如 ‘3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)’,通过这个表达式,我们除了考虑到数学的运算法则之外,还应该考虑到输入表达式过程存在的输入格式问题

    1、格式问题:表达式中存在空格,就要去除空格

    2、运算法则:有括号先去括号,先计算括号里面的没有括号的表达式;先算乘除再算加减;正负号问题,正负得负,负负得正

    3、运用正则表达式去匹配表达式中的对应的项,然后计算

    4、每一项计算出来都得反馈回那一项所在的地方

    5、有重复的东西,需要用到循环

    二、分模块进行计算(代码)

    • 1、去空格模块
    exp = '3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)'
    
    new_exp = exp.replace(' ','')
    print(new_exp)

    运行结果:

    3+(-80/2)+24*5-(18/3+4*(90/15-100)-3)
    • 2、匹配和计算括号里面没有括号的项

    先用正则表达式找出括号里面没有括号的项

    ret = re.search('([^()]+)',new_exp)
    if ret:
        exp_no_bracket = ret.group()  # 筛选出括号里面没有括号的表达式
    
    print(exp_no_bracket)

    运行结果:

    (-80/2)

    将括号里面没有括号的项去括号,然后找出单纯的乘除项,利用调用函数的方法,计算乘除结果

    def cal_exp_no_bracket(ex):  # ex是括号里面没有括号的项
        ex = ex.strip('()')  # 将里面没有括号的项的括号去除
        # 计算先乘除后加减
        ret = re.search('d+.?d*[*/]-?d+.?d*',ex)  # 利用正则表达式找第一个出现的乘除的项
        if ret:
            ex_son = ret.group()  # 子表达式,最简单的只有乘除法
            print(ex_son)
    ....
    ....
    ret = cal_exp_no_bracket(exp_no_bracket) # 调用计算括号里面没有括号的函数
    new_exp = new_exp.replace(exp_no_bracket,ret)  # 将计算括号里面没有括号的最后的值代替对应的项
    print(new_exp)


    运行结果:

    80/2

     计算原子表达式,即最简的原子形式表达式

    def cal_ex_son(ex_son):
        if '/' in ex_son:
            a,b, = ex_son.split('/')
            return str(float(a)/float(b))
        elif '*' in ex_son:
            a,b, = ex_son.split('*')
            return str(float(a) * float(b))
    ....
    .... ret
    = cal_ex_son(ex_son) # 调用计算原子表达式的函数 print(ret) new_ex = ex.replace(ex_son,ret) # 将最终计算的值替代原来括号里面没有括号的那一项

    运行结果应该是:

    -40.0
    3+-40.0+24*5-(18/3+4*(90/15-100)-3)
    • 3、匹配和计算加减法
     ret = re.findall('-?d+.?d*',ex)
                sum = 0
                for i in ret:
                    sum += float(i)
                return str(sum)
    • 4、正负符号的处理
    正负得负,负负得正
    # 正负符号的处理,正负得负,负负得正
    def dealwith(exp):
        exp = exp.replace('+-','-')
        exp = exp.replace('--','+')
        return exp
    ....
    .... new_exp
    = dealwith(new_exp) print(new_exp)

    运行结果应该是:

    3-40.0+24*5-(18/3+4*(90/15-100)-3)
    • 5、main程序

    通过函数的调用和嵌套,一步一步计算

    # 要计算的表达式
    exp = '3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)'
    # 去空格
    new_exp = exp.replace(' ','')
    print(new_exp)
    res = remove_bracket(new_exp)
    print(res)

    三、计算器总模块代码 

    以上的2和3和4点只是计算了第一个匹配到括号里面没有括号的项,以及第一个出现乘除的项,和第一个出现加减法的项,要计算全部的这样的项,需要利用循环,去实现,主要式寻找和计算括号里面没有括号的项,还有寻找和计算简单的乘除以及加减式子需要反复寻找计算,最后整理的计算器的大致框架:

    import re  # 导入re模块,正则表达式需要
    
    # 正负符号的处理,正负得负,负负得正
    def dealwith(exp):
        exp = exp.replace('+-','-')
        exp = exp.replace('--','+')
        return exp
    
    
    # 计算原子形式的表达式,两个数的乘除法
    def cal_ex_son(ex_son):
            if '/' in ex_son:
                a,b, = ex_son.split('/')
                return str(float(a)/float(b))
            elif '*' in ex_son:
                a,b, = ex_son.split('*')
                return str(float(a)*float(b))
            else:
                print('所有的乘除式子都计算好了')
    
    
    # 计算最简的括号里面没有括号的式子,先计算乘除法,再计算加减
    def cal_exp_no_bracket(ex):  # ex是括号里面没有括号的项
        ex = ex.strip('()')  # 将里面没有括号的项的括号去除  # 计算先乘除后加减
        while True:  # 利用循环找到括号里面不再有括号的项
            ret = re.search('d+.?d*[*/]-?d+.?d*',ex)  # 利用正则表达式找第一个出现的乘除的项
            if ret:  # 说明表达式中还有乘除法
                ex_son = ret.group()  # 子表达式,最简单的只有乘除法,原子形式
                print('匹配到只有乘除法的项: ',ex_son)
                ret = cal_ex_son(ex_son)  # 调用计算原子表达式的函数
                ex = ex.replace(ex_son,ret)  # 将最终计算的值替代原来括号里面没有括号的那一项
                ex = dealwith(ex)
            else:  # 说明表达式中没有乘除法,然后计算加减法
                ret = re.findall('-?d+.?d*',ex)
                sum = 0
                for i in ret:
                    sum += float(i)
                return str(sum)
    
    
    # 筛选出括号里面没有括号的表达式,并且开始计算
    def no_bracket_in_bracket(new_exp):
        while True:  # 利用循环找到所有的一层一层里面没有括号的项
            ret = re.search('([^()]+)',new_exp)
            if ret:
                exp_no_bracket = ret.group()  # 筛选出括号里面没有括号的表达式
                print('匹配到内部不再有括号的项: ',exp_no_bracket)
                ret = cal_exp_no_bracket(exp_no_bracket)  # 调用计算括号里面没有括号的项
                print(ret)
                new_exp = new_exp.replace(exp_no_bracket,ret)  # 将计算括号里面没有括号的最后的值代替对应的项
                new_exp = dealwith(new_exp)
                print(new_exp)
            else:
                print('表达式中没有括号了: ',new_exp)
                ret = cal_exp_no_bracket(new_exp)
                print(ret)
                break
    
    
    # 主程序,要计算的表达式
    exp = '3+ (-80/2)+ 24*5-(18/3+ 4*(90/15-100) -3)'
    # 去空格
    new_exp = exp.replace(' ','')
    print(new_exp)
    res = no_bracket_in_bracket(new_exp)
    print(res)

    运行结果:

    3+(-80/2)+24*5-(18/3+4*(90/15-100)-3)
    匹配到内部不再有括号的项:  (-80/2)
    匹配到只有乘除法的项:  80/2
    -40.0
    3-40.0+24*5-(18/3+4*(90/15-100)-3)
    匹配到内部不再有括号的项:  (90/15-100)
    匹配到只有乘除法的项:  90/15
    -94.0
    3-40.0+24*5-(18/3+4*-94.0-3)
    匹配到内部不再有括号的项:  (18/3+4*-94.0-3)
    匹配到只有乘除法的项:  18/3
    匹配到只有乘除法的项:  4*-94.0
    -373.0
    3-40.0+24*5+373.0
    表达式中没有括号了:  3-40.0+24*5+373.0
    匹配到只有乘除法的项:  24*5
    456.0
    None
    
    Process finished with exit code 0
  • 相关阅读:
    jdk源码调试进去形参没有值
    proxy 简化版本
    spering getBean(),IOC
    彻底清除挖矿程序
    Kworkerd恶意挖矿分析
    怎么让 Android 程序一直后台运行,像 QQ 一样不被杀死
    linux 系统下使用socket进行本地进程间通信
    linux i2c 的通信函数i2c_transfer在什么情况下出现错误
    Java Socket网络编程常见异常(转)
    踩过的坑系列之InputStream.read(byte[])方法
  • 原文地址:https://www.cnblogs.com/wxm422562/p/11098498.html
Copyright © 2020-2023  润新知