zoukankan      html  css  js  c++  java
  • Day6作业:计算器

    嗯,稀里糊涂就居然写完了......

    readme:

    程序说明:
        此计算器比较简单,只支持普通的加减乘除和小括号,不支持[],{},求幂之类的均不支持!
    
    
    测试过的字符串:
        -1/2*((60-30+(-9-2.222*-5/3*2.28/-12+7/3*99/4*2998+10*568/14)*((-40.0/5)))-(-4*3)/(16-3*2))
    
    思路:
        1.使用正则表达式,优先匹配最内层的括号内数据
        2.为了提高效率,优先把频繁用的匹配写成了compile,后期通过变量来调用
        3.无法除以0,本身除以0就是个错误的逻辑....
        4.按照优先级,先算括号,然后乘除,最后加减
        5.运行前会测试表达式中括号是否匹配
    

    流程图:

    代码:

    #!/usr/bin/env python
    # -*-coding=utf-8-*-
    # Auther:ccorz Mail:ccniubi@163.com Blog:http://www.cnblogs.com/ccorz/
    # GitHub:https://github.com/ccorzorz
    
    import re,os
    
    #提高计算效率,使用re.compile写入正则匹配,提前编译
    #匹配外部有内部没有小括号的部分
    bracket_flag_str=re.compile('(([^()]+))')
    #从左到右匹配乘除部分
    mul_div_exec_str=re.compile('d+.*d*[*/]+[+-]?d+.*d*')
    
    def sign_exec(args):
        """
        加减处理,将+-替换为-,--替换为+
        :param args: 表达式字符串
        :return: 将替换后的结果返回
        """
        return re.sub(r'+-','-',re.sub(r'-{2}','+',args))
    
    
    def add_sub_exec(args):
        """
        加减计算功能
        :param args: 字符串
        :return: 求和的结果
        """
        if args.startswith('-'):    #如果以-开头,将开头的加一个0
            args='0%s'%(args)
        elif args.startswith('+'):  #如果以+开头,将开头的+去掉
            args=re.sub(r'+','',args)
        args=re.sub(r'-','+-',args)    #将所有的-替换为+-
        args_list=re.split(r'+',args)  #以+将字符串分割为列表
        for i in args_list:
            args_list[args_list.index(i)]=float(i)  #列表中的元素转化为float类型
        result=sum(args_list)   #求和
        return result
    
    
    def exec_had_drop_contect(args):
        """
        处理括号内优先计算的函数
        :param args: 字符串
        :return: 递归函数
        """
        if not mul_div_exec_str.search(args): #如果不匹配,说明已经计算完成
            return args
        else:
            #以优先计算的部分,将字符串分割成两部分
            before,after=mul_div_exec_str.split(args,1)
            #优先计算部分定义变量
            contect=mul_div_exec_str.search(args).group()
            #如果以*分割后的列表长度大于1,计算值
            if len(contect.split('*'))>1:
                v1,v3=contect.split('*')
                v=float(v1)*float(v3)
            else:
                #处理除法
                v1,v3=contect.split('/')
                #如果除以0,提示并退出程序
                if float(v3)==float(0):
                    exit('33[31;1m学渣!!!!学渣!!!!学渣!!!!能'
                         '特么除以0么?体育老师教的数学??!!33[0m')
                else:
                    #处理除法结果
                    v=float(v1)/float(v3)
            #拼接字符串
            new_str='%s%s%s'%(before,v,after)
            #拼接后的字符串进行加减号处理
            had_sign_exec_str=sign_exec(new_str)
            #args重新赋值
            args=had_sign_exec_str
        return exec_had_drop_contect(args)
    
    
    def drop_brakets(args):
        """
        括号处理函数
        :param args: 字符串表达式
        :return: 递归函数
        """
        #如果不匹配说明已经没有括号,结束递归
        if not bracket_flag_str.search(args):
            return args
        else:
            #匹配优先的计算的内容,并且风格为3部分
            before,mid,after=bracket_flag_str.split(args,1)
            #打印分割部分,提示用户计算进度
            print(before,mid,after)
            #字符串去掉括号
            had_drop_contect=mid[1:-1]
            #计算优先部分,先计算乘除,再将结果进行加减运算
            add_sub_result=exec_had_drop_contect(had_drop_contect)
            result=add_sub_exec(add_sub_result)
            #将结果返回原来的字符串,拼接为新字符串
            args='%s%s%s'%(before,str(result),after)
        return drop_brakets(args)
    
    
    def calc(args):
        """
        计算数据函数,先处理括号部分,然后计算乘除,最后加减部分,返回结果
        :param args: 字符串
        :return: 计算结果
        """
        no_brakets=drop_brakets(args)
        no_mul_div=exec_had_drop_contect(no_brakets)
        result=add_sub_exec(no_mul_div)
        print('33[31;1m%s33[0m'%result)
    
    def check_formula(args):
        """
        判断用户输入字符串的可用性,检查括号数量是否匹配
        :param args:   #字符串
        :return:
        """
        if len(re.findall('(',args)) == len(re.findall(')',args)):
            return True
        else:
            #不匹配无法运行
            print('括号数量不匹配,确认后再输入')
            return  False
    
    #运行主函数
    if __name__ == '__main__':
        #清屏
        os.system('clear')
        print('欢迎使用只带小括号计算器'.center(60,'*'))
        inp=input('请输入你要算的表达式,除了加减乘除小括号,其他都不支持哦:')
        #先将输入的字符串去掉空白部分,以免报错
        inp=inp.strip()
        res=check_formula(inp)
        if res:
            #如果字符串符合表达式格式,进行计算
            calc(inp)
        else:
            #否则退出
            exit('输入格式有误')
    

      

  • 相关阅读:
    进程 线程 协程
    TCP的滑动窗口和网络拥塞控制
    Golang中函数结构体,将函数转换为接口
    go的调度 与 go 的GC
    未来程序员这个工种会如何进化与“35岁之殇”的思考
    golang 实现 LRU
    golang 单例模式实现
    内存泄露及内存溢出,解决方案
    Jvm调优参数
    HttpUtil
  • 原文地址:https://www.cnblogs.com/ccorz/p/5591484.html
Copyright © 2011-2022 走看看