栈的应用之中缀表达式转后缀表达式

本文详细解析了中缀表达式转换为后缀表达式的算法过程,包括无括号和带括号中缀表达式的处理方法,通过实例演示了如何利用栈的数据结构进行转换,以及提供了Python代码实现。

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

由于中缀表达式有括号的存在,其运算次序比较复杂,直接分析有些难度。先考虑不带括号的中缀表达式的转换。

由于运算符号具有不同的优先级,当前的运算符不能直接放在操作数的后面,需要考虑下一个运算符的优先级。

对比三个不同的中缀表达式转换为后缀表达式的结果

3+9*6*3\rightarrow 3 \; 9 \; 6 \;* \;3 \;*\; +

3+9+6*3\rightarrow 3\; 9\; +\; 6\; 3\; *\; +

3*9+6*3\rightarrow 3\;9\;*\;6\;3\;*\;+

可以发现:

1.后缀表达式数字的出现顺序和中缀表达式中是完全一样的。

2.中缀表达式中相邻两个运算符的优先级不一样,其在后缀表达式中的位置也不一样。其规则是,如果当前运算符优先级大于等于下个运算符优先级,将该运算符写后操作数后面。否则记下该运算符,在之后写上。

可以利用栈后进先出的特点来临时存运算符号,用一个列表存后缀表达式的结果。以

3+9*6*3\rightarrow 3 \; 9 \; 6 \;* \;3 \;*\; +

为例,演示转换的思路:

对于带有括号的中缀表达式的转换,个人理解应该将两括号之间的部分看做一个整体。遇到 ( 应压入栈,在他之后的运算符同样按照上图所示规则压入栈,直到遇到 ,表示该部分结束,应该栈里 ( 上面的所有运算符弹出。

def tokens(exp):
    """生成器函数。将输入的中缀表达式拆成一个个的项返回。但不能处理一元运算符和负数"""
    operators="+-*/()"
    i,n=0,len(exp)

    while i<n:
        if exp[i] in operators:
            yield exp[i]
            i+=1
        else:
            if exp[i]==" ":     #遇到空格跳过
                i+=1
                continue
            else:
                if i+1>=n or exp[i+1]==" " or exp[i+1] in operators: #数字后结束,或者是空格或运算符,直接加入
                    yield  exp[i]
                    i+=1
                    continue
                j=i
                while i+1<n and exp[i+1] not in operators and exp[i+1]!=" ": #数字后是数字(小数点也可以),取数字部分切片加入
                    i+=1
                yield exp[j:i+1]
                i+=1

def trans_infix_suffix(line):
    priority={"(":0,"+":1,"-":1,"*":2,"/":2}  #操作优先级,"("优先级最低
    operators="+-*/()"

    st=SStack()
    exp=[]
    for x in line:
        if x not in operators:  #是数字直接加入
            exp.append(x)
        else:
            if st.is_empty() or st.top()=="(" or x=="(": #如果栈为空,或栈顶为(,或x是(,直接入栈
                st.push(x)
            elif x==")":                                  #如果x是),弹出元素,直到栈顶为(
                while st.top()!="(":
                    exp.append(st.pop())
                st.pop()
            elif priority[x]<=priority[st.top()]:       #如果x是四则运算符,优先级小于等于栈顶元素,弹出栈顶元素,x入栈。否则直接入栈
                exp.append(st.pop())
                st.push(x)
            else:
                st.push(x)
    while not st.is_empty():                            #将栈里剩下元素弹出
        exp.append(st.pop())
    return exp

if __name__ == '__main__':
    exp=input("输入表达式:\n")
    suffix=trans_infix_suffix(tokens(exp))
    print(suffix)

测试结果:

输入表达式:
5*3*(4+6*7)*(1+1)
['5', '3', '*', '4', '6', '7', '*', '+', '*', '1', '1', '+', '*']

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值