使用栈构造后缀表达式解决简单的四则运算问题

对于四则运算表达式,中缀表达式是方便人类读懂的书写方式,而要转化为计算机方便计算的形式必须将其转换为前缀或者后缀表达式。

本文利用栈结构简单数学四则运算表达式的计算,其中仅考虑四则运算和( ),同时不考虑错误表达式的排查。

def RPN_express(m):
    """
    构造一个数字栈和一个符号栈,符号栈在如下情况下弹出压入数字栈:
    (1)遇到')',将'('之间的四则符号弹出
    (2)每一个四则符号压入前,符号栈内等级更高的符号需弹出
    @param: m  数学表达式中缀字符串
    @return: 数学表达式后缀字符串
    """
    weights = {'*': 3, '/': 3, '+': 2, '-': 2, '(': 1}
    number_stack = []
    symbol_stack = []

    for i in m:
        if i in '0123456789':
            number_stack.append(i)    # 压入数字栈
        elif i == '(':
            symbol_stack.append(i)
        elif i in weights:
            while symbol_stack and weights[symbol_stack[-1]] >= weights[i]:   # 若符号栈为非空
                number_stack.append(symbol_stack.pop())
            symbol_stack.append(i)

        elif i == ')':
            while symbol_stack and symbol_stack[-1] != '(':
                number_stack.append(symbol_stack.pop())
            else:
                symbol_stack.pop()

    while symbol_stack:
        number_stack.append(symbol_stack.pop())

    return ' '.join(number_stack)


def RPN_calculate(m):
    """
    构造一个数字栈和一个符号栈,数字和符号分别压入其中。按照如下计算规则:
    (1)当取得符号,且数字栈倒数两个为数字时,弹出这两个数字,将三者计算,并将结果压入数字栈内
    (2)当取得符号,且数字长度不足2时,压入符号栈
    (3)最后检查符号栈和数字栈,若符号栈仍有多余,一次进行弹出两个数字+一个字符的计算,再将结果压入数字栈
    @param: m  数学表达式后缀字符串
    @return: 计算结果
    """
    number_stack = []
    symbol_stack = []
    for i in m.split():
        if i in '0123456789':
            number_stack.append(i)
        elif i in '+-*/':
            if len(number_stack) >= 2:
                tmp = math_op(number_stack.pop(), number_stack.pop(), i)
                number_stack.append(tmp)
            else:
                symbol_stack.append(i)

    while symbol_stack:
        tmp = math_op(number_stack.pop(), number_stack.pop(), symbol_stack.pop())
        number_stack.append(tmp)

    assert len(number_stack) == 1
    return number_stack[0]

if __name__ == '__main__':
    string = '(1-4*7+3*(6/3+1))/2'
    print(RPN_express(string))
    print(RPN_calculate(RPN_express(string)))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值