中缀表达式转后缀表达式(python+栈实现)

本文介绍如何将常见的中缀表达式转换为后缀表达式,通过使用栈这一数据结构来实现转换过程,并提供了具体的算法步骤及Python实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中缀表达式转后缀表达式

学习过程

在网上查找资料,了解了中缀表达式和后缀表达式以及前缀表达式的定义。
中缀表达式:中缀表达式是一个通用的算术或逻辑公式表示方法, 操作符是以中缀形式处于操作数的中间。
例如:3*(5–2)+7/2
后缀表达式:后缀表达式,又称逆波兰式,指的是不包含括号,运算符放在两个运算对象的后面,所有的计算按运算符出现的顺序,严格从左向右进行(不再考虑运算符的优先规则)。
例如:3 5 2 - * 7 2 / +
前缀表达式:前缀表达式又称波兰式,前缀表达式的运算符位于操作数之前。
中缀表达式应该处于中间状态,人们在日常生活中习惯性的表达式,然而在计算机里就不好处理了,比如遇到括号里面又有运算符,运算符的结合顺序等问题。因此我们就需要将中缀表达式进行转换。如果要运算的话,转化为后缀表达式只要从左往右进行相应的计算操作,而前缀表达式从右往左一样的操作即可。

题解思路

栈是后入先出的一种数据结构,用来存放式子的运算符等符号再合适不过。

查找资料,了解到了转化思路(只考虑四则运算):

  • 从左往右扫描中缀表达式
  • 遇到操作数放入字符数组s1
  • ①遇到运算符比较和栈顶运算符的优先级:
    -如果栈空或者栈顶是左括号, 直接压入栈中
    • 否则如果优先级比栈顶运算符的高,直接压入栈中
    • 否则将栈的栈顶的运算符弹出并压入到s1中,再次转到①与栈中新的栈顶运算符相比较
  • 遇到括号:
    • 左括号:直接压入栈中
    • 右括号:则依次弹出栈的栈顶的运算符,并压入s1,直到遇到左括号为止。括号要被丢弃,即右括号不用进栈,左括号最后弹出
  • 扫描到表达式结束后,检查栈是否为空。不为空就全部弹出到s1中至空
  • 输出s1

我的代码

class Stack:
    def __init__(self):
        self._item = []

    # 添加元素
    def push(self, item):
        self._item.append(item)

    # 方法变属性
    @property
    def size(self):
        return len(self._item)

    @property
    def is_empty(self):
        return not self._item

    # 栈顶弹出
    def pop(self):
        return self._item.pop()

    # 取栈顶元素
    def peek(self):
        return self._item[-1]


stack = Stack()
i = 0
s = []
s1 = input("请输入中缀表达式:")
print(f"中缀表达式:{s1}")
s1 = list(s1)
for ch in s1:
    # 左括号入栈
    if ch == '(':
        stack.push(ch)
    # 右括号栈的运算符出栈,放到后缀表达式
    elif ch == ')':
        # 前面一个是数字加空格
        if str(s1[i-1]).isdigit():
            s.append(' ')
        while stack.peek() != '(':
            s.append(stack.pop())
            s.append(' ')
        stack.pop()  # 左括号弹出
    # 四则运算符
    # 优先级小于等于栈顶元素,栈顶元素出栈
    elif ch == '+' or ch == '-':
        # 前面一个是数字加空格
        if str(s1[i - 1]).isdigit():
            s.append(' ')
        while not stack.is_empty and stack.peek() != '(':
            s.append(stack.pop())
            s.append(' ')
        stack.push(ch)
    elif ch == '*' or ch == '/':
        # 前面一个是数字加空格
        if str(s1[i - 1]).isdigit():
            s.append(' ')
        while (not stack.is_empty) and (stack.peek() == '*' or stack.peek() == '/'):
            s.append(stack.pop())
            s.append(' ')
        stack.push(ch)
    else:
        # 当前是数字而前面一个不是数字的话加空格
        if i > 0 and not str(s1[i-1]).isdigit():
            s.append(' ')
        # 数字直接添加
        s.append(ch)
    i = i + 1
while not stack.is_empty:
    s.append(stack.pop())
    s.append('  ')
print("后缀表达式:")
print(*s)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值