返回

让栈为你解惑:轻松搞定中缀表达式求值

前端

了解后缀表达式的魅力

当我们使用计算器时,我们使用中缀表达式:操作数位于运算符两侧,例如 2 + 3。对于计算机而言,这种表示方式不太直观。为了弥补这一缺陷,后缀表达式应运而生:操作数紧随其后的运算符之后,例如 2 3 +。

利用栈的强大力量

栈,一种先进先出的数据结构,是中缀表达式求值中的秘密武器。我们将中缀表达式逐个字符扫描,并将遇到的元素压入栈中。当遇到运算符时,我们将栈顶的两个元素弹出,进行运算,并将结果压回栈中。

一步步构建后缀表达式

  1. 扫描中缀表达式: 从左到右遍历表达式。
  2. 数字压栈: 遇到数字时,直接压入栈中。
  3. 运算符处理: 遇到运算符时,判断优先级:
    • 如果优先级高于栈顶运算符,直接压入栈中。
    • 否则,依次弹出栈顶运算符,与数字运算,并将结果压栈,直至栈顶运算符优先级低于当前运算符。
  4. 表达式结束: 扫描完毕后,栈中剩余元素即为后缀表达式。

示例:求值 2 + 3 * 4

操作 栈中元素
2 2
+ 2
3 2, 3
* 2
4 2, 4

后缀表达式: 2 3 4 * +

求值过程:

操作 后缀表达式 栈中元素
初始 2 3 4 * +
3 4 * 2 3 4 * + 12
2 12 + 2 3 4 * + 14

因此,2 + 3 * 4 的值是 14

使用 Python 实现

def infix_to_postfix(infix):
    stack = []
    postfix = []
    operators = {'+': 1, '-': 1, '*': 2, '/': 2}

    for char in infix:
        if char.isdigit():
            postfix.append(char)
        elif char in operators:
            while stack and operators[stack[-1]] >= operators[char]:
                postfix.append(stack.pop())
            stack.append(char)
        elif char == '(':
            stack.append(char)
        elif char == ')':
            while stack and stack[-1] != '(':
                postfix.append(stack.pop())
            stack.pop()  # 去除'('

    while stack:
        postfix.append(stack.pop())

    return ''.join(postfix)

def evaluate_postfix(postfix):
    stack = []

    for char in postfix:
        if char.isdigit():
            stack.append(int(char))
        else:
            op2 = stack.pop()
            op1 = stack.pop()
            if char == '+':
                result = op1 + op2
            elif char == '-':
                result = op1 - op2
            elif char == '*':
                result = op1 * op2
            elif char == '/':
                result = op1 / op2
            stack.append(result)

    return stack[0]

infix_expression = "2 + 3 * 4"
postfix_expression = infix_to_postfix(infix_expression)
result = evaluate_postfix(postfix_expression)
print("中缀表达式:", infix_expression)
print("后缀表达式:", postfix_expression)
print("结果:", result)

拓展你的思维

  • 使用栈也可以解决其他问题,例如括号匹配和递归调用。
  • 中缀表达式还可以转换为前缀表达式,其中操作符位于操作数之前。
  • 探索其他算法,例如希尔排序和快速排序,它们也利用栈来提高效率。