224. Basic Calculator - cocoder39/coco39_LC GitHub Wiki
thinking process: 1. how to solve the problem if there is no parentheses 2. suppose we know how to solve step 1, then how to extend to solve the case there could be parenthesis -> stack
Notes 2022
- variant of Basic CalculatorIII doesn't work because - could be used as unary operation
- resetting res, num, sign to 0, 0, 1
- if ch == ' ': continue
- if digit: build up the number
- if (:
- 3.1 push res and sign to stack
- 3.1.1 one ( maps to 2 new elements being added to stack
- 3.2 once the result within () is ready, new_res = res + sign * result
- 3.1 push res and sign to stack
- if ):
- 4.1 evaluate the result within () result = res + sign * num
- 4.2 evaluate the effect of applying result to the previous evaluation result
- 4.2.1 res = pre_res + pre_sign * result
- 4.2.2 one ) maps to 2 pop operations from stack so at the end stack is supposed to be empty
- 4.3 stack is empty at the end as ( and ) are pairing
- no need to reset sign. if there is sign after ), sign will be reset properly
- if +/-:
- 5.1 evaluate result and update sign and num
class Solution:
def calculate(self, s: str) -> int:
num_stack = []
sign_stack = [] # can use same stack, as long as we follow pattern to insert (ie number then sign)
res = 0 # res of current layer
num = 0 # last built number in current layer
sign = 1 # sign of last built number in current layer
for ch in s:
if ch.isdigit():
num = num * 10 + ord(ch) - ord('0')
elif ch == '+': # res sign num +
res += sign * num
sign = 1
num = 0
elif ch == '-': # res sign num -
res += sign * num
sign = -1
num = 0
elif ch == '(': # res sign (
num_stack.append(res)
sign_stack.append(sign)
res = 0
num = 0
sign = 1
elif ch == ')': # res sign num )
res += sign * num
pre_res = num_stack.pop()
pre_sign = sign_stack.pop()
res = pre_res + pre_sign * res
num = 0
# no need to reset sign here
# this happens only if num is outside of ()
# if num is within (), it has been reset to 0
return res + sign * num
==========================================================================
A op1 (B op2 C) => push A and op1 into stack, calculate result within parentheses, thus final result = result * op1 + A
int calculate(string s) {
int res = 0;
int num = 0;
int sign = 1;
stack<int> stk;
for (int i = 0, len = s.length(); i < len; i++) {
if (isdigit(s[i])) {
num = num * 10 + (s[i] - '0');
} else if (s[i] == '+') { // end of preceding num
res += sign * num;
sign = 1;
num = 0;
} else if (s[i] == '-') { // end of preceding num
res += sign * num;
sign = -1;
num = 0;
} else if (s[i] == '(') { // at the start position or following an operator
stk.push(res);
stk.push(sign);
res = 0;
sign = 1;
// num = 0; // can be ignored
} else if (s[i] == ')') { // follows a number
res += sign * num; // result between a pair of parentheses
num = 0;
res *= stk.top();
stk.pop();
res += stk.top();
stk.pop();
}
}
res += sign * num;
return res;
}