描述
请写一个整数计算器,支持加减乘三种运算和括号。
数据范围:0≤∣s∣≤100,保证计算结果始终在整型范围内
要求:空间复杂度: O(n),时间复杂度 O(n)
示例 :
示例1 | 示例2 | 示例3 |
输入: "1+2" 返回值: 3 | 输入: "(2*(3-4))*5" 返回值: -10 | 输入: "3+2*3*4-1" 返回值: 26 |
思路:
实现整数计算器,就是要实现整数进行运算的算法。整数运算涉及到两个问题,一是运算优先级,二是括号。
对于运算优先级,我们知道,括号优先级高于乘除法,高于加减法。遇到乘法符号时先处理乘法,将其他数暂时存储起来,乘法处理完毕之后,再处理加减法。
对于括号,可将括号中的部分看成一个新的表达式,对括号中的表达式计算调用递归。处理括号时,当遇到一个左括号,即意味着进入了子问题,直到遇到右括号代表递归结束。
终止条件:遇到左括号就进入子问题,调用递归,遇到右括号就代表子问题结束,即本次递归结束。将括号内的计算结果饭回。
算法步骤:
这里将减法也当作了加法(将减法看作加入原数的相反数的加法),这时只有两种运算法则。
step 1:使用栈辅助处理优先级,默认符号为加号。
step 2:遍历字符串,遇到数字,则将连续的数字字符部分转化为int型数字。
step 3:遇到左括号,则将括号内的部分送入递归,处理子问题;遇到右括号代表已经到了这个子问题的结尾,结束继续遍历字符串,将子问题的加法部分相加为一个数字,返回。
step 4:当遇到符号的时候如果是+,得到的数字正常入栈,如果是-,则将其相反数入栈,如果是*,则将栈中内容弹出与后一个元素相乘再入栈。
step 5:最后将栈中剩余的所有元素,进行一次全部相加。
图示:
代码实现:
class Solution:
def solve(self, s):
s = s.strip()
st = []
num = 0
sign = '+'
res = 0
index = 0
while index < len(s):
if s[index] == ' ':
index += 1
continue
# 遇到左括号时
if s[index] == '(':
end = index + 1
lens = 1
while lens > 0:
if s[end] == '(':
lens += 1
if s[end] == ')':
lens -= 1
end += 1
# 将括号视为子问题进入递归
num = self.solve(s[index + 1:end - 1])
index = end - 1
continue
# 字符数字转化为int数字
if '0' <= s[index] <= '9':
num = num * 10 + int(s[index])
# 根据符号运算
if not '0' <= s[index] <= '9' or index == len(s) - 1:
# 加
if sign == '+':
st.append(num)
# 减
elif sign == '-':
st.append(-num)
elif sign == '*':
st.append(st.pop() * num)
num = 0
sign = s[index]
index += 1
# 栈中元素相加
while st:
res += st.pop()
return res