返回

双栈算法:解锁表达式计算中的万能钥匙

后端

对于技术从业者而言,表达式计算是软件开发中不可或缺的一部分。从简单的算术运算到复杂的逻辑表达式,我们经常需要高效且准确地对表达式求值。双栈算法提供了一种通用的解决方案,使我们能够优雅地应对各种表达式计算场景。

双栈的精髓

双栈算法的核心思想是使用两个栈:操作数栈和运算符栈。操作数栈存储数字,而运算符栈存储运算符。当我们遍历表达式时,我们将操作数压入操作数栈,并将运算符压入运算符栈。

一旦运算符栈的顶部有两个运算符和操作数栈的顶部有两个操作数,我们就可以执行运算。我们将两个操作数弹出,执行运算,并将结果压入操作数栈。然后,我们弹出运算符栈顶部的运算符。

通用性强:适用于多种表达式

双栈算法的强大之处在于它的通用性。它可以处理各种类型的表达式,包括:

  • 前缀表达式(逆波兰表示法)
  • 中缀表达式(我们熟悉的传统数学表达式)
  • 后缀表达式(波兰表示法)

通过灵活调整操作和操作数的入栈和出栈规则,双栈算法能够适应不同的表达式格式。

代码实现:简洁高效

下面是一个简单的双栈算法的 Python 实现:

class Solution:
    def calculate(self, s: str) -> int:
        op_stack, num_stack = [], []
        ops = {"+": lambda x, y: x + y, "-": lambda x, y: x - y, "*": lambda x, y: x * y, 
               "/": lambda x, y: int(x / y)}

        for token in s.split():
            if token.isdigit():
                num_stack.append(int(token))
            elif token in ops:
                op_stack.append(token)
            else:
                op = op_stack.pop()
                num2, num1 = num_stack.pop(), num_stack.pop()
                result = ops[op](num1, num2)
                num_stack.append(result)

        return num_stack[0]

举例说明

让我们使用双栈算法来计算表达式 (1 + 2) * 3

  1. 遍历表达式: 逐个处理表达式中的每个符号。
  2. 入栈操作数: 遇到数字 1,将其压入操作数栈。
  3. 入栈运算符: 遇到运算符 +,将其压入运算符栈。
  4. 入栈操作数: 遇到数字 2,将其压入操作数栈。
  5. 执行运算: 运算符栈顶部的运算符是 +,操作数栈顶部的两个操作数是 21。执行 2 + 1,并将结果 3 压入操作数栈。
  6. 出栈运算符: 弹出运算符栈顶部的运算符 +
  7. 入栈运算符: 遇到运算符 *,将其压入运算符栈。
  8. 入栈操作数: 遇到数字 3,将其压入操作数栈。
  9. 执行运算: 运算符栈顶部的运算符是 *,操作数栈顶部的两个操作数是 33。执行 3 * 3,并将结果 9 压入操作数栈。
  10. 出栈运算符: 弹出运算符栈顶部的运算符 *
  11. 返回结果: 操作数栈中只剩下一个元素,即计算结果 9

结论

双栈算法为表达式计算提供了通用、高效且灵活的解决方案。它广泛应用于编译器、计算器和其他需要对表达式求值的场景中。通过了解双栈算法的原理,我们可以提高我们的编程技能并轻松应对各种表达式计算问题。