目录
题目一 leetcode224. 基本计算器
1.题目描述
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。
示例 1:
输入: "1 + 1"
输出: 2
示例 2:输入: " 2-1 + 2 "
输出: 3
示例 3:输入: "(1+(4+5+2)-3)+(6+8)"
输出: 23
说明:你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。
2.解题思路
递归处理括号,我们用一个变量cnt,遇到左括号自增1,遇到右括号自减1,当cnt为0的时候,说明括号正好完全匹配,这个trick在验证括号是否valid的时候经常使用到。然后我们就是根据左右括号的位置提取出中间的子字符串调用递归函数,返回值赋给num
参考连接:https://www.cnblogs.com/grandyang/p/4570699.html
3.代码实现
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
res = 0
num = 0
sign = 1
n = len(s)
i = 0
while i < n:
if s[i] >= "0" and s[i] <= "9":
num = num*10 + int(s[i])
elif s[i] == "(":
j = i
cnt = 0
while i < n:
if s[i] == "(":
cnt+=1
if s[i] == ")":
cnt-=1
if cnt == 0:
break
# break后就不会再执行i+1了,所以i还是指向")"
i+=1
num = self.calculate(s[j+1:i])
if s[i] == "+" or s[i] == "-" or i == n-1:
res += sign*num
num=0
sign = 1 if s[i] == "+" else -1
i+=1
return res
题目二 leetcode227. 基本计算器 II
1.题目描述
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。
示例 1:
输入: "3+2*2"
输出: 7
示例 2:输入: " 3/2 "
输出: 1
示例 3:输入: " 3+5 / 2 "
输出: 5
说明:你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。
2.解题思路
由于存在运算优先级,我们采取的措施是使用一个栈保存数字,如果该数字之前的符号是加或减,那么把当前数字压入栈中,注意如果是减号,则加入当前数字的相反数,因为减法相当于加上一个相反数。如果之前的符号是乘或除,那么从栈顶取出一个数字和当前数字进行乘或除的运算,再把结果压入栈中,那么完成一遍遍历后,所有的乘或除都运算完了,再把栈中所有的数字都加起来就是最终结果了(stack.pop(0))
3.代码实现
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
op = "+"
n = len(s)
res = 0
num = 0
stack = []
for i in range(n):
if s[i] <= "9" and s[i] >= "0":
num = num * 10 + int(s[i])
if s[i] == '+' or s[i] == '-' or s[i] == '*' or s[i] == '/' or i == n-1:
if op == '+':
stack.append(num)
elif op == '-':
stack.append(-num)
elif op == "*":
t = stack.pop(-1) * num
stack.append(t)
else:
if stack[-1] > 0:
t = stack.pop(-1) // num
else:
t = -(-stack.pop(-1) // num)
stack.append(t)
num = 0
op = s[i]
while stack:
# stack.pop(-1) 也行
res = res + stack.pop(0)
return res
题目三 leetcode772. 基本计算器 III
1.题目描述
实现一个基本的计算器来计算简单的表达式字符串。
表达式字符串可以包含左括号 ( 和右括号 ),加号 + 和减号 -,非负 整数和空格 。
表达式字符串只包含非负整数, +, -, *, / 操作符,左括号 ( ,右括号 )和空格 。整数除法需要向下截断。
你可以假定给定的字符串总是有效的。所有的中间结果的范围为 [-2147483648, 2147483647]。
一些例子:
"1 + 1" = 2
" 6-4 / 2 " = 4
"2*(5+5*2)/3+(6/2+8)" = 21
"(2+6* 3+5- (3*14/7+2)*5)+3"=-12
注:不要 使用内置库函数 eval。
2.解题思路
其实做过前两道题的话,那么这道题也就没什么问题,因为把前两道题的解法综合一下就是这道题的解法啦。由于此题既有括号,又有乘除法,我们知道括号是优先级最高的,但是好就好在我们可以将括号里的内容当作一个整体调用递归函数来处理。而其他部分,就跟第二道一模一样了。我们还是分情况来处理遍历,我们需要几个变量,num 表示当前的数字,curRes 表示当前的结果,res 为最终的结果,op 为操作符号,初始化为 '+'。当遇到数字的时候,我们将 num 自乘以 10 并加上这个数字,这是由于可能遇到多位数,所以每次要乘以 10。当遇到括号的时候,这里就有一个小 trick,由于表示可能会有括号嵌套括号,所以我们如果搜索右括号的话,就有可能使得括号没有正确的匹配上,所以我们用一个变量 cnt,遇到左括号自增1,遇到右括号自减1,当 cnt 为0的时候,说明括号正好完全匹配,这个 trick 在验证括号是否 valid 的时候经常使用到。然后我们就是根据左右括号的位置提取出中间的子字符串调用递归函数,返回值赋给 num。如果遇到符号,或者是最后一个位置的字符时,我们根据 op 的值对 num 进行分别的加减乘除的处理,结果保存到 stack 中。然后将num 重置为0。最后将当前字符s[ i ]赋值给 op(注意这里只有当时最后一个位置的字符时,才有可能不是运算符号,不过也不要紧了,因为遍历已经结束了)
3.代码实现
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
op = "+"
n = len(s)
res = 0
num = 0
stack = []
i = 0
while i < n:
if s[i] >= "0" and s[i] <= "9":
num = num*10 + int(s[i])
elif s[i] == "(":
j = i
cnt = 0
while i < n:
if s[i] == "(":
cnt+=1
if s[i] == ")":
cnt-=1
if cnt == 0:
break
# break后i+1不再计算
i+=1
num = self.calculate(s[j+1:i])
if s[i] == '+' or s[i] == '-' or s[i] == '*' or s[i] == '/' or i == n-1:
# op是上一个遇到的操作符
if op == '+':
stack.append(num)
elif op == '-':
stack.append(-num)
elif op == "*":
t = stack.pop(-1) * num
stack.append(t)
else:
# 解决python的负数下取整
if stack[-1] > 0:
t = stack.pop(-1) // num
else:
t = -(-stack.pop(-1) // num)
stack.append(t)
num = 0
op = s[i]
i+=1
while stack:
# stack.pop(-1) 也行
res = res + stack.pop(0)
return res