实现计算器是很经典的题目,包括之前在数据结构课上也遇到过。
这次又在leetcode上刷到了基础计算器的一系列题,做个总结。
首先先看看最简单的一种情况:字符串中只有加减号,还有非负整数
举个栗子,“1+14-5”
定义三个变量,分别为num(保存当前的操作数),op(保存数字前的运算符号),用res记录累加结果。
具体操作步骤如下:
- 遍历字符串的每个元素。
- 如果指针指向数字,则更新num值。
- 如果指针指向操作符,则根据之前保存的op和num对res累加。再更新op为当前指向的操作符
- 如果指针指向末尾元素,则更新num值,并更新res。
可能看起来不太好理解,下面就挨个细说~
现在指向数字1,更新num值为1
现在指向操作符+,此时op为1(表示+号),num值为1,更新res:
res = res + op*num = 1
更新op为1(现在指向为+),num为0
现在指向数字1,更新num值为1
现在指向数字4,更新num值为14(可以想想是怎么更新的?)
现在指向操作符‘-‘。此时op为1,num为14,更新res:
res = res + op * num = 15
更新op为-1(此时操作符为’-’),num为0
现在指向末尾元素5.此时更新num为5
另外,此时op为-1,更新res:
res = res + op * num = 10
至此,结束。
可以看到,这里没有运算符号优先级的问题,也没有括号优先级的问题,因此也不必用栈。
接下来,我们就基于此,一步步拓展。
.
基本计算器:包括括号
这是leetcode上的一道困难题。
这里的写法参考了这位老哥。我这里相当是把他的代码拿过来做一个解析。
首先我们分析问题,这个问题相对于上面的easy模式增加了一个括号。
括号代表什么?括号代表着要对括号内的式子单独处理
也就是说,我们要想办法把括号内的式子和括号外的式子分开,直到括号内单独处理结束之后,再进行合处理
因此,我们这里用栈这种数据结构,大致方法如下:
- 当遍历到元素“(”时,将res(前面式子的值)和op(括号左边的操作符)压入栈中,等待取用。
- 当遍历到元素“)"时(此时括号内的式子计算完成),从栈中pop出old_res和old_op,从而对res更新。
代码如下:
class Solution:
def calculate(self, s: str) -> int:
res, num, op = 0, 0, 1
stack = []
for c in s:
if c.isdigit(): # isdigit方法判断c是否为数字
num = num * 10 + int(c