问题概述:
题目要求实现一个基本计算器来计算字符串形式的数学表达式。该表达式有效且可能包含数字、运算符(+、-、*、/)以及括号。运算符之间没有空格,并且运算中的除法结果需要保留整数部分。
算法思路:
-
操作符优先级: 运算符有不同的优先级,乘法和除法优先级高于加法和减法。因此,处理表达式时需要考虑运算符的优先级,确保按顺序正确计算。
-
使用栈:
- 数字栈 (
num_stack) :用于存储操作数。 - 运算符栈 (
op_stack) :用于存储运算符和括号。括号的作用是控制运算顺序。
- 数字栈 (
-
步骤:
-
遍历表达式中的每个字符:
- 如果字符是数字,则构建完整的数字并推入数字栈。
- 如果字符是运算符,则根据栈中的运算符优先级进行计算,直到栈顶运算符的优先级低于当前运算符,或者遇到括号。
- 如果遇到左括号
(,直接压栈。 - 如果遇到右括号
),则弹出栈中的运算符进行计算,直到遇到左括号(。
-
最后,栈中可能还有一些运算符未处理,需要继续计算并返回结果。
-
-
运算过程: 运算符的处理通过一个辅助函数
operate(a, b, op)完成,该函数根据不同的运算符执行相应的操作。
关键点:
- 运算符优先级:确保正确处理乘除法和加减法。
- 括号处理:遇到括号时,将内部表达式作为一个子问题递归处理,计算完后再回到外部表达式。
- 整数除法:使用
//运算符保证除法结果为整数。
代码解析:
代码详细解析:
-
operate(a, b, op):辅助函数,用于根据运算符对两个数进行计算。支持加法、减法、乘法和除法(整除)。 -
precedence字典:定义了运算符的优先级,乘法和除法优先级高于加法和减法。它用于决定何时将栈中的运算符出栈进行计算。 -
num_stack和op_stack:两个栈分别用于存储数字和运算符。数字栈用于保存操作数,运算符栈用于保存运算符和括号。 -
遍历表达式:
- 当遇到数字时,将其转换为整数并推入
num_stack。 - 当遇到运算符时,根据栈中的优先级进行处理。如果当前运算符的优先级低于栈顶运算符的优先级,则弹出栈顶运算符并进行计算,然后将当前运算符压入栈中。
- 当遇到左括号时,直接将其压入运算符栈中,表示开始一个新的子表达式。
- 当遇到右括号时,弹出栈中的运算符进行计算,直到遇到左括号,表示一个子表达式计算完成。
- 当遇到数字时,将其转换为整数并推入
-
最终计算:
- 遍历完表达式后,栈中可能还剩下未计算的运算符,继续计算直到栈为空。
-
返回结果:
- 返回数字栈中的最终结果,即为表达式的值。
时间复杂度分析:
- 时间复杂度:O(n),其中
n是表达式的长度。每个字符最多被访问一次,栈操作(入栈、出栈)也是常数时间操作,因此总的时间复杂度是 O(n)。 - 空间复杂度:O(n),栈最多存储
n个元素(在极端情况下,表达式中可能所有字符都是数字或运算符)。