返回

速览栈在计算器实现中的灵魂作用

后端

一个优雅的计算器,离不开栈的身影。栈,这个在计算机科学中鼎鼎大名的数据结构,以其简洁高效、后进先出的特性,成为计算器实现的基石。它就像一位幕后英雄,默默守护着计算过程的稳定与流畅。

栈在计算器中的灵魂作用

  1. 简化计算过程 :栈可以将复杂的问题分解成多个简单的步骤,从而简化计算过程。
  2. 处理复杂问题 :栈可以处理括号配对、表达式求值等复杂问题。
  3. 支持后缀表达式 :栈天然适合处理后缀表达式,简化了计算器的实现。

手把手实现一个简易版本的计算器

1. 构建栈

class Stack:
    def __init__(self):
        self.items = []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[-1]

    def is_empty(self):
        return self.items == []

2. 解析中缀表达式

def parse_infix_expression(expression):
    """
    将中缀表达式转换成后缀表达式。

    参数:
        expression: 要转换的中缀表达式。

    返回:
        转换后的后缀表达式。
    """

    # 运算符优先级字典
    operator_precedence = {
        "+": 1,
        "-": 1,
        "*": 2,
        "/": 2,
        "(": 0,
        ")": 0
    }

    # 输出队列
    output_queue = []

    # 操作符栈
    operator_stack = Stack()

    # 遍历中缀表达式
    for token in expression:
        # 如果是操作数,直接加入输出队列
        if token not in operator_precedence:
            output_queue.append(token)
        # 如果是左括号,压入操作符栈
        elif token == "(":
            operator_stack.push(token)
        # 如果是右括号,弹出操作符栈中的所有运算符,直到遇到左括号
        elif token == ")":
            while operator_stack.peek() != "(":
                output_queue.append(operator_stack.pop())
            operator_stack.pop()
        # 如果是运算符,比较其优先级与操作符栈顶元素的优先级
        else:
            while not operator_stack.is_empty() and operator_precedence[token] <= operator_precedence[operator_stack.peek()]:
                output_queue.append(operator_stack.pop())
            operator_stack.push(token)

    # 将剩余的操作符弹出操作符栈,并加入输出队列
    while not operator_stack.is_empty():
        output_queue.append(operator_stack.pop())

    # 返回后缀表达式
    return " ".join(output_queue)

3. 计算后缀表达式

def evaluate_postfix_expression(expression):
    """
    计算后缀表达式。

    参数:
        expression: 要计算的后缀表达式。

    返回:
        计算结果。
    """

    # 创建一个栈来存储操作数
    operand_stack = Stack()

    # 遍历后缀表达式
    for token in expression.split():
        # 如果是操作数,压入操作数栈
        if token not in ["+", "-", "*", "/"]:
            operand_stack.push(int(token))
        # 如果是运算符,从操作数栈中弹出两个操作数,并进行计算
        else:
            operand2 = operand_stack.pop()
            operand1 = operand_stack.pop()
            result = 0
            if token == "+":
                result = operand1 + operand2
            elif token == "-":
                result = operand1 - operand2
            elif token == "*":
                result = operand1 * operand2
            elif token == "/":
                result = operand1 / operand2
            operand_stack.push(result)

    # 返回计算结果
    return operand_stack.pop()

4. 使用栈实现计算器

def calculator():
    """
    创建一个简单的计算器。
    """

    # 提示用户输入中缀表达式
    expression = input("请输入中缀表达式:")

    # 将中缀表达式转换为后缀表达式
    postfix_expression = parse_infix_expression(expression)

    # 计算后缀表达式
    result = evaluate_postfix_expression(postfix_expression)

    # 打印计算结果
    print("计算结果为:", result)


if __name__ == "__main__":
    calculator()