简单四则运算解析器 | 豆包MarsCode AI刷题

51 阅读3分钟

问题概述

题目要求实现一个基本计算器来计算字符串形式的数学表达式。该表达式有效且可能包含数字、运算符(+-*/)以及括号。运算符之间没有空格,并且运算中的除法结果需要保留整数部分。

算法思路

  1. 操作符优先级: 运算符有不同的优先级,乘法和除法优先级高于加法和减法。因此,处理表达式时需要考虑运算符的优先级,确保按顺序正确计算。

  2. 使用栈

    • 数字栈 (num_stack) :用于存储操作数。
    • 运算符栈 (op_stack) :用于存储运算符和括号。括号的作用是控制运算顺序。
  3. 步骤

    • 遍历表达式中的每个字符:

      • 如果字符是数字,则构建完整的数字并推入数字栈。
      • 如果字符是运算符,则根据栈中的运算符优先级进行计算,直到栈顶运算符的优先级低于当前运算符,或者遇到括号。
      • 如果遇到左括号 (,直接压栈。
      • 如果遇到右括号 ),则弹出栈中的运算符进行计算,直到遇到左括号 (
    • 最后,栈中可能还有一些运算符未处理,需要继续计算并返回结果。

  4. 运算过程: 运算符的处理通过一个辅助函数 operate(a, b, op) 完成,该函数根据不同的运算符执行相应的操作。

关键点

  • 运算符优先级:确保正确处理乘除法和加减法。
  • 括号处理:遇到括号时,将内部表达式作为一个子问题递归处理,计算完后再回到外部表达式。
  • 整数除法:使用 // 运算符保证除法结果为整数。

代码解析

image.png

代码详细解析

  1. operate(a, b, op) :辅助函数,用于根据运算符对两个数进行计算。支持加法、减法、乘法和除法(整除)。

  2. precedence 字典:定义了运算符的优先级,乘法和除法优先级高于加法和减法。它用于决定何时将栈中的运算符出栈进行计算。

  3. num_stackop_stack:两个栈分别用于存储数字和运算符。数字栈用于保存操作数,运算符栈用于保存运算符和括号。

  4. 遍历表达式

    • 当遇到数字时,将其转换为整数并推入 num_stack
    • 当遇到运算符时,根据栈中的优先级进行处理。如果当前运算符的优先级低于栈顶运算符的优先级,则弹出栈顶运算符并进行计算,然后将当前运算符压入栈中。
    • 当遇到左括号时,直接将其压入运算符栈中,表示开始一个新的子表达式。
    • 当遇到右括号时,弹出栈中的运算符进行计算,直到遇到左括号,表示一个子表达式计算完成。
  5. 最终计算

    • 遍历完表达式后,栈中可能还剩下未计算的运算符,继续计算直到栈为空。
  6. 返回结果

    • 返回数字栈中的最终结果,即为表达式的值。

时间复杂度分析

  • 时间复杂度:O(n),其中 n 是表达式的长度。每个字符最多被访问一次,栈操作(入栈、出栈)也是常数时间操作,因此总的时间复杂度是 O(n)。
  • 空间复杂度:O(n),栈最多存储 n 个元素(在极端情况下,表达式中可能所有字符都是数字或运算符)。