python实现能分辨优先级(+-*/)和括号的计算器

    能够识别四则运算的优先级和括号的计算器,其难点在于如何在遇到乘号、除号或者是括号时暂时不计算前面的加法,而先把乘法(除法或者是括号内的计算式)先计算出来,比如1+2*3,如何在读到2的时候不直接和1相加,而是先和3相乘,单看这一点是比较容易的,因为可以再多读一个符号,判断是否为乘号或者是除号,若是,先计算后面的整体,然后接着读一个符号,若还是乘号或者除号,就继续读、继续算,直到读到的不是乘号或者是除号为止。但是若引入括号又该怎么办?一般对于括号中的内容采用递归的方法解决。这就是大致思路,但是到底是先判断括号还是先判断乘除号?可以这样考虑:跟在一个运算符号(也就是+、-、*、/)后面的,要么是一个括号括起来的表达式如+(2+3),要么就是一个数字如+2,这是只需要先判断是否是括号符号"(",若是,则对整个括号内的内容进行递归;若不是(,也就意味着这个运算符号后面跟的是一个数字,则判断这个数字后面的符号是否是乘除号,若是就将其整体递归计算出来,若不是,则直接与前一个数字进行加减操作。

    先贴出只能对括号进行处理的代码(不能判断乘除的优先级)(两个计算器我各自写成了一个函数,都可以直接调用):

    这里是先单独读取第一个数字(整体),然后循环读取一个符号和符号后的数字(整体)(这里的整体是指被括号括起来的部分),对每个整体分别进行计算后再将整体之间的内容进行计算。用到了递归。

def simpleArithmetic():
    #x存储表达式
    #loc记录当前读取位置
    #count用于将括号和括回进行匹配
    #locStart记录被括号括起来的整体的起始位置,locEnd则记录结束位置(不包括那一对括号)
    x = input("input your expression")
    def cal(exp):
        loc = 0
        count = 0
        #读入第一个数字/整体(被括号括起来的)
        firstNum = exp[loc]
        if firstNum != "(":
            result = int(firstNum)
            loc += 1
        else:
            locStart = loc + 1
            count += 1  # 为了将( 与 ) 进行匹配
            while count != 0:
                loc += 1
                if exp[loc] == "(":
                    count += 1
                elif exp[loc] == ")":
                    count -= 1
            locEnd = loc
            loc += 1
            result = cal(exp[locStart:locEnd])
        #读取后面的符号和数字/整体
        while loc < len(exp):
            operator = exp[loc]
            loc += 1
            secNum = exp[loc]
            if secNum != "(":
                loc += 1
            else:
                locStart = loc+1
                count += 1#为了将( 与 ) 进行匹配
                while count != 0:
                    loc += 1
                    if exp[loc] == "(":
                        count += 1
                    elif exp[loc] == ")":
                        count -= 1
                locEnd = loc
                loc += 1
                secNum = cal(exp[locStart:locEnd])
            if operator == "+":
                    result += int(secNum)
            elif operator == "-":
                    result -= int(secNum)
            elif operator == "*":
                    result = result * int(secNum)
            else:
                    result = result / int(secNum)
        return result
    return cal(x)

    然后是能够识别优先级和括号的代码:

    注释里的整体就是指被乘除号连接起来的整体如1+2*3*4中的2*3*4

def smartArithmetic1():
    #x存储表达式
    #loc记录当前读取位置
    #count用于将括号和括转进行匹配
    #locStart记录被括号括起来的整体的起始位置,locEnd则记录结束位置(不包括那一对括号)
    x = input("input your expression")
    def cal(exp):
        loc = 0
        count = 0
        # 读入第一个数字/整体(被括号括起来的)
        firstNum = exp[loc]
        if firstNum != "(":
            result = int(firstNum)
            loc += 1
        else:
            locStart = loc + 1
            count += 1  # 为了将( 与 ) 进行匹配
            while count != 0:
                loc += 1
                if exp[loc] == "(":
                    count += 1
                elif exp[loc] == ")":
                    count -= 1
            locEnd = loc
            loc += 1
            result = cal(exp[locStart:locEnd])
        while loc < len(exp):
            operator = exp[loc]
            loc += 1
            #完善第一个整体,即若后面有跟*或者/时读进来计算为一个整体
            while operator == "*" or operator =="/":
                secNum = exp[loc]
                if secNum != "(":
                    loc += 1
                else:
                    locStart = loc+1
                    count += 1#为了将( 与 ) 进行匹配
                    while count != 0:
                        loc += 1
                        if exp[loc] == "(":
                            count += 1
                        elif exp[loc] == ")":
                            count -= 1
                    locEnd = loc
                    loc += 1
                    secNum = cal(exp[locStart:locEnd])
                if operator == "*":
                        result = result * int(secNum)
                else:
                        result = result / int(secNum)
                if loc >= len(exp):
                    break
                operator = exp[loc]
                loc += 1
            #加号或者减号
            operator1 = operator
            if loc >= len(exp):
                break
            secNum = exp[loc]
            if secNum != "(":
                secNum = int(secNum)
                loc += 1
            else:
                locStart = loc + 1
                count += 1  # 为了将( 与 ) 进行匹配
                while count != 0:
                    loc += 1
                    if exp[loc] == "(":
                        count += 1
                    elif exp[loc] == ")":
                        count -= 1
                locEnd = loc
                loc += 1
                secNum = cal(exp[locStart:locEnd])
            #完善第二个加数/减数
            if loc < len(exp):
                operator = exp[loc]
                loc += 1
                flag = False
                while operator == "*" or operator =="/":
                    flag = True
                    thirdNum = exp[loc]
                    if thirdNum != "(":
                        loc += 1
                    else:
                        locStart = loc+1
                        count += 1#为了将( 与 ) 进行匹配
                        while count != 0:
                            loc += 1
                            if exp[loc] == "(":
                                count += 1
                            elif exp[loc] == ")":
                                count -= 1
                        locEnd = loc
                        loc += 1
                        thirdNum = cal(exp[locStart:locEnd])
                    if operator == "*":
                        secNum = secNum * int(thirdNum)
                    else:
                        secNum = secNum / int(thirdNum)
                    if loc >= len(exp):
                        break
                    operator = exp[loc]
                    loc += 1
                if not flag:
                    loc -= 1
            if operator1 == "+":
                result += int(secNum)
            else:
                result -= int(secNum)
            if loc >= len(exp):
                break
        return result
    return cal(x)

测试效果:(目前这个针对了整数,浮点数还没测试,可以把int改为float试一下)

 

 

博主写python没多久,可能有些不规范(第二个代码里面有很多重复的代码,比如读取整体和完善整体的代码,可以整合成函数),还请多多见谅23333。还有就是这个代码没有测试很多用例,可能会有bug,如果有请在评论区发出有错的测试用例,thx。

后面还有一篇用栈和递归实现同样功能的文章,这篇文章里面的代码要规整一些,其中有借鉴别人的代码https://blog.csdn.net/KevinLML/article/details/86590697

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值