Given a string s
representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation. You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval()
. The string s
consists of digits, '+'
, '-'
, '('
, ')'
, and ' '
. The string s
represents a valid expression. '+'
is not used as a unary operation (i.e., "+1"
and "+(2 + 3)"
is invalid). '-'
could be used as a unary operation (i.e., "-1"
and "-(2 + 3)"
is valid). There will be no two consecutive operators in the input. Every number and running calculation will fit in a signed 32-bit integer. For example:
s = "1 + 1"
should return 2
s = " 2-1 + 2 "
should return 3
s = "(1+(4+5+2)-3)+(6+8)"
should return 23
Given a string s
representing a valid expression, implement a basic calculator to evaluate it, and return the result of the evaluation.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval()
.
Examples:
Input: s = "1 + 1"
Output: 2
Input: s = " 2-1 + 2 "
Output: 3
Input: s = "(1+(4+5+2)-3)+(6+8)"
Output: 23
A naive approach would be to try to directly parse the string and perform calculations as we encounter operators and numbers. However, this becomes complex with parentheses and operator precedence. Using eval()
is obviously not allowed. Thus, this makes this problem quite tricky.
The most efficient way to solve this is using a stack. The stack will help us keep track of the sign and intermediate results when we encounter parentheses. Here's how the algorithm works:
+
or -
, update the sign.(
, push the current result and sign onto the stack and reset the result and sign for the subexpression.)
, pop the sign and previous result from the stack and use them to calculate the result of the subexpression.class Solution:
def calculate(self, s: str) -> int:
stack = []
result = 0
sign = 1
i = 0
while i < len(s):
if s[i].isdigit():
num = 0
while i < len(s) and s[i].isdigit():
num = num * 10 + int(s[i])
i += 1
result += sign * num
i -= 1 # Correct the index after the inner loop
elif s[i] == '+':
sign = 1
elif s[i] == '-':
sign = -1
elif s[i] == '(':
stack.append(result)
stack.append(sign)
result = 0
sign = 1
elif s[i] == ')':
result = stack.pop() * result + stack.pop() # sign * result + prev_result
i += 1
return result
s
. We iterate through the string once.