返回
双栈算法:解锁表达式计算中的万能钥匙
后端
2023-12-08 09:18:57
对于技术从业者而言,表达式计算是软件开发中不可或缺的一部分。从简单的算术运算到复杂的逻辑表达式,我们经常需要高效且准确地对表达式求值。双栈算法提供了一种通用的解决方案,使我们能够优雅地应对各种表达式计算场景。
双栈的精髓
双栈算法的核心思想是使用两个栈:操作数栈和运算符栈。操作数栈存储数字,而运算符栈存储运算符。当我们遍历表达式时,我们将操作数压入操作数栈,并将运算符压入运算符栈。
一旦运算符栈的顶部有两个运算符和操作数栈的顶部有两个操作数,我们就可以执行运算。我们将两个操作数弹出,执行运算,并将结果压入操作数栈。然后,我们弹出运算符栈顶部的运算符。
通用性强:适用于多种表达式
双栈算法的强大之处在于它的通用性。它可以处理各种类型的表达式,包括:
- 前缀表达式(逆波兰表示法)
- 中缀表达式(我们熟悉的传统数学表达式)
- 后缀表达式(波兰表示法)
通过灵活调整操作和操作数的入栈和出栈规则,双栈算法能够适应不同的表达式格式。
代码实现:简洁高效
下面是一个简单的双栈算法的 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
,将其压入操作数栈。 - 执行运算: 运算符栈顶部的运算符是
+
,操作数栈顶部的两个操作数是2
和1
。执行2 + 1
,并将结果3
压入操作数栈。 - 出栈运算符: 弹出运算符栈顶部的运算符
+
。 - 入栈运算符: 遇到运算符
*
,将其压入运算符栈。 - 入栈操作数: 遇到数字
3
,将其压入操作数栈。 - 执行运算: 运算符栈顶部的运算符是
*
,操作数栈顶部的两个操作数是3
和3
。执行3 * 3
,并将结果9
压入操作数栈。 - 出栈运算符: 弹出运算符栈顶部的运算符
*
。 - 返回结果: 操作数栈中只剩下一个元素,即计算结果
9
。
结论
双栈算法为表达式计算提供了通用、高效且灵活的解决方案。它广泛应用于编译器、计算器和其他需要对表达式求值的场景中。通过了解双栈算法的原理,我们可以提高我们的编程技能并轻松应对各种表达式计算问题。