Python小练习四——计算器

本文介绍了一个使用Python实现的复杂数学表达式解析器。该解析器能够处理包含多重嵌套括号、四则运算及小数的复杂数学公式,并通过递归方式逐步简化表达式直至得出最终结果。

题目要求

写出一个计算器,可以计算下面的公式:
1 - 2 * ((60 - 30 + (-40.0 / 5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14)) - (-4 * 3) / (16 - 3 * 2))

流程图

这里写图片描述

代码

#!/usr/bin/env python3
import re
from decimal import Decimal #python的小数字类型

def jiajian(a):
    zhuan_huan = 0 #判断拆掉括号后,×/与-号相遇的情况,先按正的算,然后在加上负号
    if '*-' in a or '/-' in a:
        a = re.sub('\*\-' , '*', a)
        a = re.sub('\/\-', '/', a)
        zhuan_huan = 1
    b = re.split("[\+|\-]", a) #根据加减号分离数字
    c = re.split("[\d]", a) #根据数字分离出运算符号
    d = [] #用来存放需要运算的符号
    # print("c:",c)

    if c[0] == '-': #处理数字前面有负号的情况
        for i in range(len(b)):
            if b[i] != '':
                b[i] = '-' + b[i]
                break
    for i in c: #将用来运算的符号添加
        if i and i not in '*/.':
            d.append(i)
    # print("the jiajian b:",b)
    for index,i in enumerate(b): #检查是否有乘除运算的表达式
        if ("*" in i) or ("/" in i):
            b[index] = cheng_chu(i, zhuan_huan) #进行乘运算
    if c[0] == '-':#处理数字前面有负号的情况
        d.pop(0)
    if b[0] == '': #处理数字前面有负号的情况
        b.pop(0)
    # print("The jia ", b)
    # print("The jia fu", d)
    # print(len(d))
    if len(d) != 0:
        for i,j in enumerate(d):#进行加减运算
            if j == '+':
                b[i+1] = Decimal(b[i]) + Decimal(b[i + 1])
            elif j == "-":
                b[i + 1] = Decimal(b[i]) - Decimal(b[i + 1])
            else:
                print("加减符号错误")
    # print("aaaaa")
    return b[-1]


def cheng_chu(a, zhuan_huan):
    b = re.split('[\*\/]', a) #根据加乘除分离数字
    c = re.split('\d+', a) #根据数字分离出运算符号
    d = [] #用来存放需要运算的符号
    # print("a:",a)
    # print("c:",c)
    for i in c: #将需要运算的符号加入到d中
        if i and i not in '.' and i not in "-":
            d.append(i)
    # print("The cheng", b)
    for i,j in enumerate(d):
        if j == '*':
            b[i+1] = Decimal(b[i]) * Decimal(b[i + 1])
        elif j == "/":
            b[i + 1] = Decimal(b[i]) / Decimal(b[i + 1])
        else:
            print(";惩处符号错误")
    if zhuan_huan == 1: #如果之前有负号的话在加上负号
        b[-1] = -b[-1]
    return (b[-1])

def get_bracket(the_str):
    the_str = re.sub(' ', '', the_str)#替换空格
    try:#判断是否有括号,有的话进行递归,没有的话进行最后一次运算结束递归
        expression = re.search('\([\+\-\*\/]?\d+\.?\d*(([\+\-\*\/]\d+\.?\d*){1,})\)', the_str).group()
    except AttributeError:
        return jiajian(the_str)
    expression_2 = expression[1:-1] #除去括号得到表达式
    res = jiajian(expression_2) #计算表达式
    # print("res:", res)
    expression = "\\" + expression[:-1] + "\\" + expression[-1:] #格式化括号,让re模块把()当做字符
    the_str = re.sub('\+\-', '-', the_str) #同样的格式化
    the_str = re.sub('\+\+', '+', the_str)
    the_str = re.sub('\-\+', '-', the_str)
    the_str = re.sub('\-\-', '+', the_str)
    # print("srt:" ,the_str)
    # print("expression:", expression)
    expression = re.sub('\+', '\+', expression) #同样的格式化
    expression = re.sub('\-', '\-', expression)
    expression = re.sub('\*', '\*', expression)
    the_str = re.sub(expression, str(res), the_str) #将算好的结果与表达式替换
    # print("srt:",the_str)
    return get_bracket(the_str) #进行递归


if __name__ == "__main__":
    s = '1 - 2 * ((60 - 30 + (-40.0 / 5) * (9 - 2 * 5 / 3 + 7 / 3 * 99 / 4 * 2998 + 10 * 568 / 14)) - (-4 * 3) / (16 - 3 * 2))'
    res = get_bracket(s)
    print(res)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值