将字符串转化成后缀表达式进行求值

总体思想如下:

  • 将运算符合操作数分开,原理为操作符之前为操作数。
  • 将中缀表达式转换为后缀表达式,并在转化的过程中直接求值。
  • 具体细节代码中有注释,如果有什么不明白的地方可以私信,如有bug欢迎改正。
# 擦作数的优先级1>2,任意定义即可
ops_rule = {
    '+': 1,
    '-': 1,
    '*': 2,
    '/': 2
}


def cal(n1, n2, op):
    if op == '+':
        return n1 + n2
    if op == '-':
        return n1 - n2
    if op == '*':
        return n1 * n2
    if op == '/':
        return n1 / n2


def stringToFloat(string):
    # print(string)
    return float(string)


# # 字符串计算
# string = '2+3.1*4-8.2/2'
string = '((9+(3*(4-2))*((3+10)/2)))'
stackValue = []
stackOp = []
# 拆分字符串
start = 0  # 用于记录操作数起始位置
fuHao = ['+', '-', '*', '/', '(', ')']
for i, elem in enumerate(string):
    if elem in fuHao:
        # 操作数压栈
        if len(string[start:i]) != 0:  # 防止括号和操作数相邻导致操作数起始位置错误
            stackValue.append(stringToFloat(string[start:i]))
            # print(stackValue, stackOp)
        start = i + 1
        if elem == '(':
            start = i + 1
            stackOp.append(elem)
        elif elem == ')':  # 运算符一直出栈
            start = i + 1
            # 如果当前操作符为')'则将操作符一直出栈直到stackOp为空或者遇到'('为止。
            while True:
                op = stackOp[-1]
                if op == '(': # 遇到'('停止出栈
                    stackOp.pop()
                    break
                else:
                    # 操作符出栈,先出栈为右操作数
                    stackOp.pop()
                    n2 = stackValue.pop()
                    n1 = stackValue.pop()
                    result = cal(n1, n2, op)
                    stackValue.append(result)
                    # stackOp.append(elem)
        # 如果为'+', '-', '*', '/'则遵循将比当前操作数(elem)优先级大的或者相等的操作数(op)出栈即op>=elem,直到stackOp空或者遇到'('为止。
        else:
            while len(stackOp) > 0:
                op = stackOp[-1] # 访问之前的的操作数
                # 如果遇到'('停止出栈
                if op == '(':
                    break
                # 将比当前操作数(elem)优先级大的或者相等的操作数(op)出栈即op>=elem
                if ops_rule[elem] > ops_rule[op]:
                    break
                else:
                    op = stackOp.pop()
                    n2 = stackValue.pop()
                    n1 = stackValue.pop()
                    result = cal(n1, n2, op)
                    stackValue.append(result)
            stackOp.append(elem)
# 将最后的数字压入stackValue栈中,不用空格隔开这个地方就不好弄
if len(string[start:-1]) != 0:
    if string[-1] == ')':
        stackValue.append(stringToFloat(string[start:-1]))
else:
    if len(string[start:]) != 0:
        stackValue.append(stringToFloat(string[start:]))
# print(stackValue)
# print(stackOp)
# 运算符全部出栈
while len(stackOp) > 0:
    op = stackOp.pop()
    if op == '(':
        continue
    n2 = stackValue.pop()
    n1 = stackValue.pop()
    result = cal(n1, n2, op)
    stackValue.append(result)
# 打印结果
print(stackValue[0])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值