Python3.5计算器之复杂表达式运算

一、需求
有这么一个表达式:
1 - 2 * ((60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2)))
通过Python实现,自动判断括号以及加减乘除的运算优先级,得出运算结果,显示运算步骤
同时允许用户自己输入表达式(限+-*/()),正确回显计算结果
二、技术
Python3正则表达式+函数递归
三、源码实现
#coding=utf-8
#Version:python3.5.2
#Tools:Pycharm
__author__ = "Colby"
import re,os,sys
'''
计算这表达式的值:1 - 2 * ((60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2)))
'''
def format_mark(express):
    '''
    表达式替换过程中可能出现一些组合符号,
    机器无法辨别,此函数负责处理这些组合符号
    :param express: 
    :return: 
    '''
    express = express.replace('+-', '-')
    express = express.replace('-+', '-')
    express = express.replace('++', '+')
    express = express.replace('--', '+')
    express = express.replace('*+', '*')
    express = express.replace('+*', '*')
    express = express.replace('+/', '/')
    express = express.replace('/+', '/')
    return express
def com_jiajian(express):
    '''
    :param express: 
    :return: 
    '''
    expr = express
    sub_expr = re.search(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", expr)
    if not sub_expr:
        return expr
    else:
        sub_expr2 = sub_expr.group()
        # print('sub_expr1',sub_expr1,'19行结果express:',div_express)
        if len(sub_expr2.split('+')) > 1:
            n1, n2 = sub_expr2.split('+')
            result = float(n1)+float(n2)
        else:
            n1, n2 = sub_expr2.split('-')
            result = float(n1) - float(n2)
        re_sub_expr = re.sub(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", str(result), expr, count=1)
        # 反复调用除法
        print('加减运算:',re_sub_expr)
        bb = com_jiajian(str(re_sub_expr))
        return bb
def com_chengchu(expr_div):
    '''
    :param expr_div: 
    :return: 
    '''
    expr=expr_div
    sub_expr = re.search(r"\d+\.?\d*[\/\*]\-?\d+\.?\d*",expr)
    if not sub_expr:
        return expr
    else:
        sub_expr2 = sub_expr.group()
        if len(sub_expr2.split('/')) > 1:
            n1, n2 = sub_expr2.split('/')
            result = float(n1)/float(n2)
        if len(sub_expr2.split('*')) > 1:
            n1, n2 = sub_expr2.split('*')
            result = float(n1)*float(n2)
        else:
            #只计算乘除,加减直接pass,放入加减函数执行
            pass
        re_sub_expr=re.sub(r"\d+\.?\d*[\/\*]\-?\d+\.?\d*",str(result),expr,count=1)
        #反复调用除法
        print('乘除运算:',re_sub_expr)
        bb=com_chengchu(format_mark(re_sub_expr))
        return bb
def compute(express):
    express = com_chengchu(format_mark(express))
    express = com_jiajian(format_mark(express))
    return express
def delkuohao(express):
    #检测表达式是否存在括号,如果存在就去括号,否则直接执行
    res=re.compile(r'[()]')
    sub_expr1 = re.search('(\([\+\-\*\/\.0-9]+\))', express)
    if not sub_expr1:
        return express
    else:
        sub_expr1=sub_expr1.group()
        #delkuohao(express)
        #匹配括号,将计算结果替换到表达式
        sub_expr2=sub_expr1[1:len(sub_expr1)-1]
        sub_expr3=compute(sub_expr2)
        sub_expr3 = re.sub('(\([\+\-\*\/\.0-9]+\))', str(sub_expr3),express,count=1)
        print('括号运算:',sub_expr3)
        delkuohao_expr=delkuohao(format_mark(sub_expr3))
        return delkuohao_expr
if __name__=="__main__":
    #while True:
    #express=input("请输入要计算的表达式:")
    print('\n================================')
    print('\033[33m 混合运算计算器\033[0m')
    print('================================')
    #express ='1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'
    while True:
        express = input('\033[32m请输入表达式,规范点哦 | (退出:q)\033[0m')
        express = re.sub('\s*', '', express)
        if len(express) == 0:
            continue
        elif express == 'q':
            sys.exit('退出程序')
        elif re.search('[^0-9\.\-\+\*\/\(\)]',express):
            print('\033[31m 不是有效的算数表达式哦,请重新输入!!!\033[0m')
        else:
            express = express.replace(' ', '')
            print('您输入的表达式:',express)
            '''调用去除括号的函数'''
            express2 = delkuohao(express)
            #删除括号
            express2 = compute(format_mark(express2))
            #删除括号后再调用一次计算函数
            print('\033[31m表达式:%s'%express,'=', str(express2),'\033[0m')
四、运算步骤如下:
================================
 混合运算计算器
================================
请输入表达式,规范点哦 | (退出:q)1 - 2 * ((60-30 +(-40.0/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2)))
您输入的表达式: 1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)))
乘除运算: -8.0
括号运算: 1-2*((60-30+-8.0*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)))
乘除运算: 9-10.0/3+7/3*99/4*2998+10*568/14
乘除运算: 9-3.3333333333333335+7/3*99/4*2998+10*568/14
乘除运算: 9-3.3333333333333335+2.3333333333333335*99/4*2998+10*568/14
乘除运算: 9-3.3333333333333335+231.00000000000003/4*2998+10*568/14
乘除运算: 9-3.3333333333333335+57.75000000000001*2998+10*568/14
乘除运算: 9-3.3333333333333335+173134.50000000003+10*568/14
乘除运算: 9-3.3333333333333335+173134.50000000003+5680.0/14
乘除运算: 9-3.3333333333333335+173134.50000000003+405.7142857142857
加减运算: 5.666666666666666+173134.50000000003+405.7142857142857
加减运算: 173140.1666666667+405.7142857142857
加减运算: 173545.88095238098
括号运算: 1-2*((60-30-8.0*173545.88095238098)-(-4*3)/(16-3*2)))
乘除运算: 60-30-1388367.0476190478
加减运算: 30.0-1388367.0476190478
加减运算: -1388337.0476190478
括号运算: 1-2*(-1388337.0476190478-(-4*3)/(16-3*2)))
乘除运算: -12.0
括号运算: 1-2*(-1388337.0476190478--12.0/(16-3*2)))
乘除运算: 16-6.0
加减运算: 10.0
括号运算: 1-2*(-1388337.0476190478+12.0/10.0))
乘除运算: -1388337.0476190478+1.2
加减运算: -1388335.8476190479
括号运算: 1-2*-1388335.8476190479)
乘除运算: 1--2776671.6952380957)
加减运算: 2776672.6952380957)
表达式:1-2*((60-30+(-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))) = 2776672.6952380957) 
发布了35 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/colby_chenlun/article/details/75009811