Python逆波兰表达式

12 篇文章 0 订阅
9 篇文章 1 订阅

1.先创建SqStack类,用于操作顺序栈

class SqStack:
    # 构造函数
    def __init__(self):
        self.data = []  # 声明空列表,作为栈的存放元素

    # 判断栈是否为空
    def empty(self):
        if len(self.data) == 0:
            return True
        return False

    # 进栈
    def push(self, item):
        self.data.append(item)

    # 出栈
    def pop(self):
        assert not self.empty()  # 判断栈是否为为空
        return self.data.pop()  # pop() 函数用于移除列表中的一个元素(默认最后一个元素),并且返回该元素的值。

    # 取栈顶元素
    def get_top(self):
        assert not self.empty()
        return self.data[-1]  # data[-1]取出倒数第一个数

2.创建ExpressClass类,用于获取中缀表达式转后缀表达式(逆波兰表达式),以及获取后缀表达式的值

  1. 创建init构造函数
  2. 创建get_post_exp函数,获取后缀表达式
  3. 创建trans函数,中缀表达式转后缀表达式
  4. 创建get_value,获取后缀表达式的值
from SqStack import SqStack


class ExpressClass:
    def __init__(self, str):
        self.exp = str  # 中缀表达式存放位置
        self.post_exp = []  # 后缀表达式存放位置

    def get_post_exp(self):  # 返回后缀表达式
        return self.post_exp

    def trans(self):  # 中缀转后缀
        opor = SqStack()  # 创建空栈
        i = 0  # 栈下标
        while i < len(self.exp):
            ch = self.exp[i]  # 取出栈元素
            if ch == "(":  # 遇到左括号,入符号栈
                opor.push(ch)
            elif ch == ")":  # 遇到右括号,需要取出符号栈元素,追加到后缀表达式栈中
                while not opor.empty() and opor.get_top() != "(":
                    e = opor.pop()  # 将"("之前的所有元素退栈,因为在栈中"("之前的意思是在"("后进去的元素,出来的时候在"("之前出
                    self.post_exp.append(e)  # 把符号追加到后缀栈中
                opor.pop()  # 將“(”退栈
            elif ch == "+" or ch == "-":  # 入符号栈
                # 先取出符号栈的栈顶元素,判断是否是(,如果不是,则把符号栈的符号取出来入后缀表达式栈
                while not opor.empty() and opor.get_top() != "(":
                    e = opor.pop()
                    self.post_exp.append(e)
                # 如果符号栈是(,则直接入栈
                opor.push(ch)
            elif ch == "*" or ch == "/":  # 入符号栈
                while not opor.empty():
                    e = opor.get_top()  # 获取栈顶元素
                    if e != "(" and (e == "*" or e == "/"):
                        e = opor.pop()
                        self.post_exp.append(e)
                    else:
                        break
                opor.push(ch)  # 把符号入栈

            else:  # 就是数字,入后缀表达式栈
                d = ""  # 保存数字
                # 判断是否是数字
                while "0" <= ch <= "9":  # 判断是否为数字,如果是,则一直取出所有数字
                    d += ch
                    i += 1
                    if i < len(self.exp):  # 如果当前项为最后一项,因为先加1,则会超出索引,所以要先判断,超出最后一项,则结束所有循环,也就是break
                        ch = self.exp[i]  # 取出当前下标的元素
                    else:
                        break  # 退出所有循环
                i -= 1  # 循环完毕则退格,减1只适合最大2位数的数字运算
                self.post_exp.append(int(d))  # 后缀表达式入
            i += 1
        # 判断符号栈是否为空,没空,就把元素压入后缀栈中
        while not opor.empty():
            self.post_exp.append(opor.pop())

    # 获取后缀表达式的值
    def get_value(self):
        opand = SqStack()  # 创建空栈  # 创建空栈
        i = 0  # 栈的下标
        while i < len(self.post_exp):
            opv = self.post_exp[i]  # 从头0取出栈中的元素
            if opv == "+":  # 如果遇到+
                a, b = opand.pop(), opand.pop()
                c = a + b
                opand.push(c)  # 计算结果再放入栈
            elif opv == "-":
                a, b = opand.pop(), opand.pop()  # 此处先获取a,再获取b,入栈时,减数后入,出栈时减数先出,所以a是减数
                c = b - a
                opand.push(c)  # 计算结果再放入栈

            elif opv == "*":
                a, b = opand.pop(), opand.pop()
                c = a * b
                opand.push(c)  # 计算结果再放入栈
            elif opv == "/":
                a, b = opand.pop(), opand.pop()  # 此处先获取a,再获取b,入栈时,分母后入,出栈时分母先出,所以a是分母
                assert a != 0  # 分母不为0
                c = b / a
                opand.push(c)  # 计算结果再放入栈
            else:
                opand.push(opv)  # 如果不是符号,则直接入栈opand
            i += 1
        return opand.get_top()  # 返回栈顶元素

3.最后创建main类

from ExpressClass import ExpressClass

if __name__ == '__main__':
    ex = ExpressClass("(56-20)/(4+2)")
    ex.trans()
    print(ex.get_post_exp())
    print(ex.get_value())


我们测试一下(56-20)/(4+2), 得如下图

扩展:无栈类实现

原理都是一样的,只是把栈类换成列表

# 未使用SqStack类
def get_value(str):
    opand = []  # 创建空栈  # 创建空栈
    i = 0  # 栈的下标
    while i < len(str):
        opv = str[i]  # 从头0取出栈中的元素
        if opv == "+":  # 如果遇到+
            a, b = opand.pop(), opand.pop()
            c = int(a) + int(b)
            opand.append(c)  # 计算结果再放入栈
        elif opv == "-":
            a, b = opand.pop(), opand.pop()  # 此处先获取a,再获取b,入栈时,减数后入,出栈时减数先出,所以a是减数
            c = int(b) - int(a)
            opand.append(c)  # 计算结果再放入栈

        elif opv == "*":
            a, b = opand.pop(), opand.pop()
            c = int(a) * int(b)
            opand.append(c)  # 计算结果再放入栈
        elif opv == "/":
            a, b = opand.pop(), opand.pop()  # 此处先获取a,再获取b,入栈时,分母后入,出栈时分母先出,所以a是分母
            assert a != 0  # 分母不为0
            c = int(b) / int(a)
            opand.append(c)  # 计算结果再放入栈
        else:
            opand.append(opv)  # 如果不是符号,则直接入栈opand
        i += 1
    return opand[-1]  # 返回栈顶元素


if __name__ == '__main__':
    ipt = input()
    ipt = list(ipt.split())
    re = get_value(ipt)
    print(re)

测试案例:[56, 20, '-', 4, 2, '+', '/']

  • 35
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 39
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小星博博

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值