Skip to content

Commit 3fb14ae

Browse files
committed
224 Basic Calculator py3
1 parent c1abde0 commit 3fb14ae

File tree

2 files changed

+79
-14
lines changed

2 files changed

+79
-14
lines changed

224 Basic Calculator py3.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/python3
2+
"""
3+
Implement a basic calculator to evaluate a simple expression string.
4+
5+
The expression string may contain open ( and closing parentheses ), the plus +
6+
or minus sign -, non-negative integers and empty spaces .
7+
8+
Example 1:
9+
10+
Input: "1 + 1"
11+
Output: 2
12+
Example 2:
13+
14+
Input: " 2-1 + 2 "
15+
Output: 3
16+
Example 3:
17+
18+
Input: "(1+(4+5+2)-3)+(6+8)"
19+
Output: 23
20+
Note:
21+
You may assume that the given expression is always valid.
22+
Do not use the eval built-in library function.
23+
"""
24+
from typing import List
25+
26+
27+
class Solution:
28+
def calculate(self, s: str) -> int:
29+
"""
30+
1. treat +/- as unary operator
31+
2. maintain stk of operands to sum
32+
3. handle bracket recursively
33+
"""
34+
ret, _ = self.eval(s + "\0", 0, [])
35+
return ret
36+
37+
def eval(self, s: str, start: int, stk: List[int]) -> int:
38+
prev_op = "+"
39+
operand = 0
40+
i = start
41+
while i < len(s): # not using for-loop, since the cursor needs to advance in recursion
42+
if s[i] == " ":
43+
pass
44+
elif s[i].isdigit():
45+
operand = operand * 10 + int(s[i])
46+
elif s[i] in ("+", "-", ")", "\0"): # delimited
47+
if prev_op == "+":
48+
stk.append(operand)
49+
elif prev_op == "-":
50+
stk.append(-operand)
51+
52+
if s[i] in ("+", "-"):
53+
operand = 0
54+
prev_op = s[i]
55+
elif s[i] in (")", "\0"):
56+
return sum(stk), i
57+
elif s[i] == "(":
58+
# avoid setting operand to 0
59+
operand, i = self.eval(s, i + 1, [])
60+
else:
61+
raise
62+
63+
i += 1
64+
65+
66+
if __name__ == "__main__":
67+
assert Solution().calculate("(1+(4+5+2)-3)+(6+8)") == 23

772 Basic Calculator III.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,21 @@ def calculate(self, s: str) -> int:
3030
"""
3131
s = s + "\0" # signal the end
3232
ret, _ = self.eval(s, 0, [])
33-
print(ret)
3433
return ret
3534

3635
def eval(self, s, i, stk):
36+
"""
37+
return the cursor since the cursor advances in recursion
38+
"""
3739
operand = 0
3840
prev_op = "+"
3941
while i < len(s):
4042
c = s[i]
4143
if c == " ":
42-
i += 1
44+
pass # not continue since need trigger i += 1
4345
elif c.isdigit():
4446
operand = operand * 10 + int(c)
45-
i += 1
46-
elif c in ("+", "-", "*", "/", ")", "\0"): # delimited
47+
elif c in ("+", "-", "*", "/", ")", "\0"): # delimiter
4748
if prev_op == "+":
4849
stk.append(operand)
4950
elif prev_op == "-":
@@ -55,22 +56,19 @@ def eval(self, s, i, stk):
5556
prev_operand = stk.pop()
5657
stk.append(int(prev_operand / operand))
5758

58-
operand = 0
59-
prev_op = c
60-
i += 1
61-
62-
if c == ")":
59+
if c in ("+", "-", "*", "/"):
60+
operand = 0
61+
prev_op = c
62+
elif c in (")", "\0"):
6363
return sum(stk), i
64-
65-
elif c == "(":
64+
elif c == "(": # "(" is not delimiter
6665
operand, i = self.eval(s, i + 1, [])
67-
# elif c == ")":
68-
# return sum(stk), i + 1
6966
else:
7067
raise
7168

72-
return sum(stk), i
69+
i += 1
7370

7471

7572
if __name__ == "__main__":
73+
assert Solution().calculate("(( ( ( 4- 2)+ ( 6+ 10 ) )+ 1) /( ( ( 7 + 9 )* ( 5*8) )- ( 5 + ( 2 * 10 ) ) ) )") == 0
7674
assert Solution().calculate("(2+6* 3+5- (3*14/7+2)*5)+3") == -12

0 commit comments

Comments
 (0)