赞
踩
实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格 。 整数除法仅保留整数部分。
示例 1:
输入: "3+2*2"
输出: 7
示例 2:
输入: " 3/2 "
输出: 1
示例 3:
输入: " 3+5 / 2 "
输出: 5
-
as negative numbers说是栈的经典应用,结果好难做,哭哭
最基本的题目,参考了这篇题解:https://leetcode-cn.com/problems/basic-calculator-ii/solution/chai-jie-fu-za-wen-ti-shi-xian-yi-ge-wan-zheng-ji-/
首先讨论只有+, -
的情况,对于每个数,用sign
来表示这个数字之前的符号,然后碰到新的符号后,就把之前的带符号数字入栈,然后根据字符串中的符号,更新每个数字前的符号。这样做的意义是,把减法变成了数字内部的,最后可以直接求所有栈内数字的总和. Similar to word count in MapReduce.
如果增加了*, /
符号,那么上面的做法有一点就不行了,不能在最后求栈内数字的总和了。又因为,*, /
的优先级比+, -
要高,所以可以稍作修改:当发现当前数字前面的符号是*, /
时,就先运算一下(用此时栈顶的元素和当前元素做运算),然后把运算结果加入到栈里面。最后同样地求栈内总和即可。
Time complexity:
o
(
n
)
o(n)
o(n)
Space complexity:
o
(
n
)
o(n)
o(n)
If it’s *
or /
, then calculate and put the result into stack. Otherwise put the number into stack. After preprocessing, the stack only contains numbers and +
, -
, and looks like: num1, +, num2, -, num3, ...
Go through the stack again to calculate the +
and -
.
Time complexity:
o
(
n
)
o(n)
o(n)
Space complexity:
o
(
n
)
o(n)
o(n)
class Solution: def calculate(self, s: str) -> int: def read_number(s: str, index: int) -> tuple: """ Read number Returns: number: int new_i: new index """ number = 0 while index < len(s) and s[index].isdigit(): number = number * 10 + int(s[index]) index += 1 return number, index stack = [] i = 0 while i < len(s): if s[i].isdigit(): number, i = read_number(s, i) if stack and stack[-1] in ('*', '/'): op, num1 = stack.pop(), stack.pop() if op == '*': stack.append(number * num1) elif op == '/': stack.append(num1 // number) else: stack.append(number) elif s[i] in ('+', '-', '*', '/'): stack.append(s[i]) i += 1 else: i += 1 res = 0 for i in range(2, len(stack), 2): num1, op, num2 = stack[i - 2], stack[i - 1], stack[i] if op == '+': res = num1 + num2 elif op == '-': res = num1 - num2 stack[i] = res return stack[-1]
-
as negative numbersclass Solution: def calculate(self, s: str) -> int: stack = [] op, sign = 0, '+' s += '+0' for ch in s: if ch.isdecimal(): op = op * 10 + int(ch) elif ch == '+' or ch == '-' or ch == '*' or ch == '/': if sign == '+' or sign == '-': stack.append(op * (1 if sign == '+' else -1)) elif sign == '*': stack[-1] *= op elif sign == '/': stack[-1] = int(stack[-1] / op) op = 0 sign = ch return sum(stack)
如果是带括号的计算器的话,就用递归计算括号内的内容。递归的时候需要对原输入做改变,比如计算"3 * (1 - 2) + 3 / (2 - 1)"
时,对(1 - 2)
递归后,下一次应该从+
开始了,所以传入一个list
并且用pop
的方式来访问list
内的元素
加了对括号的处理,代码如下:
class Solution: def calculate(self, s: str) -> int: def helper(s: collections.deque) -> int: ans, op = 0, 0 sign = '+' stack = [] while s: ch = s.popleft() if ch.isdecimal(): op = op * 10 + int(ch) elif ch == '+' or ch == '-' or ch == '*' or ch == '/': if sign == '+' or sign == '-': stack.append(op * (1 if sign == '+' else -1)) elif sign == '*': stack[-1] *= op elif sign == '/': stack[-1] = int(stack[-1] / op) op = 0 sign = ch elif ch == '(': op = helper(s) elif ch == ')': if sign == '+' or sign == '-': stack.append(op * (1 if sign == '+' else -1)) elif sign == '*': stack[-1] *= op elif sign == '/': stack[-1] = int(stack[-1] / op) break return sum(stack) return helper(collections.deque(s + '+0'))
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。