Python将中缀表达式转换为后缀表达式

将中缀表达式转换为后缀表达式

遵循以下步骤:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从左至右扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是左括号“(”,则直接压入S1;
(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最右边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。

例如,将中缀表达式“1+((2+3)×4)-5”转换为后缀表达式的过程如下:

扫描到的元素S2(栈底->栈顶)S1 (栈底->栈顶)说明
11数字,直接入栈
+1+S1为空,运算符直接入栈
(1+ (左括号,直接入栈
(1+ ( (同上
21 2+ ( (数字
+1 2+ ( ( +S1栈顶为左括号,运算符直接入栈
31 2 3+ ( ( +数字
)1 2 3 ++ (右括号,弹出运算符直至遇到左括号
×1 2 3 ++ ( ×S1栈顶为左括号,运算符直接入栈
41 2 3 + 4+ ( ×数字
)1 2 3 + 4 ×+右括号,弹出运算符直至遇到左括号
-1 2 3 + 4 × +--与+优先级相同,因此弹出+,再压入-
51 2 3 + 4 × + 5-数字
到达最右端1 2 3 + 4 × + 5 -S1中剩余的运算符

因此结果为“1 2 3 + 4 × + 5 -”。

代码:
# coding:utf-8
def priority(z):
    if z in ['×', '*', '/']:
        return 2
    elif z in ['+', '-']:
        return 1


def in2post(expr):
    """ :param expr: 前缀表达式
        :return: 后缀表达式

        Example:
            "1+((2+3)×4)-5"
            "1 2 3 + 4 × + 5 -"
    """
    stack = []  # 存储栈
    post = []  # 后缀表达式存储
    for z in expr:
        if z not in ['×', '*', '/', '+', '-', '(', ')']:  # 字符直接输出
            post.append(z)
            print(1, post)
        else:
            if z != ')' and (not stack or z == '(' or stack[-1] == '('
                             or priority(z) > priority(stack[-1])):  # stack 不空;栈顶为(;优先级大于
                stack.append(z)     # 运算符入栈

            elif z == ')':  # 右括号出栈
                while True:
                    x = stack.pop()
                    if x != '(':
                        post.append(x)
                        print(2, post)
                    else:
                        break

            else:   # 比较运算符优先级,看是否入栈出栈
                while True:
                    if stack and stack[-1] != '(' and priority(z) <= priority(stack[-1]):
                        post.append(stack.pop())
                        print(3, post)
                    else:
                        stack.append(z)
                        break
    while stack:    # 还未出栈的运算符,需要加到表达式末尾
        post.append(stack.pop())
    return post

if __name__ == '__main__':
    s = "1+((2+3)×4)-5"
    post = in2post(s)
    print('后缀表达式: ',post)
    
## 输出:
# 1 ['1']
# 1 ['1', '2']
# 1 ['1', '2', '3']
# 2 ['1', '2', '3', '+']
# 1 ['1', '2', '3', '+', '4']
# 2 ['1', '2', '3', '+', '4', '×']
# 3 ['1', '2', '3', '+', '4', '×', '+']
# 1 ['1', '2', '3', '+', '4', '×', '+', '5']
# 后缀表达式:  ['1', '2', '3', '+', '4', '×', '+', '5', '-']
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值