Given a string s
which represents an expression, evaluate this expression and return its value.
The integer division should truncate toward zero.
You may assume that the given expression is always valid. All intermediate results will be in the range of [-231, 231 - 1]
.
Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval()
.
Example 1:
Input: s = "3+2*2" Output: 7
Example 2:
Input: s = " 3/2 " Output: 1
Example 3:
Input: s = " 3+5 / 2 " Output: 5
Constraints:
1 <= s.length <= 3 * 105
s
consists of integers and operators ('+', '-', '*', '/')
separated by some number of spaces.s
represents a valid expression.[0, 231 - 1]
.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The most straightforward way to solve this is to evaluate the expression piece by piece. We read the entire input and perform calculations in the order we encounter the operators.
Here's how the algorithm would work step-by-step:
def calculate(input_string): current_number = 0
previous_operator = '+'
stack = []
string_length = len(input_string)
for index in range(string_length): character = input_string[index]
if character.isdigit(): current_number = (current_number * 10) + int(character)
if character in '+-*/' or index == string_length - 1:
# Apply previous operator and update the stack for +/-
if previous_operator == '+':
stack.append(current_number)
elif previous_operator == '-':
stack.append(-current_number)
elif previous_operator == '*':
stack.append(stack.pop() * current_number)
else:
stack.append(int(stack.pop() / current_number))
previous_operator = character
current_number = 0
# Sum up remaining values in stack after mult/div are processed.
result = sum(stack)
return result
The efficient solution handles math problems in a specific order, focusing on the most important operations first. It processes multiplication and division before addition and subtraction to get the correct result without needing parentheses. This prevents the need to evaluate the entire equation at once, thus saving time and space.
Here's how the algorithm would work step-by-step:
def calculate(expression):
current_number = 0
stack = []
last_operation = '+'
for i, character in enumerate(expression):
if character.isdigit():
current_number = (current_number * 10) + int(character)
if character in '+-*/' or i == len(expression) - 1:
# Perform multiplication and division before addition and subtraction.
if last_operation == '+':
stack.append(current_number)
elif last_operation == '-':
stack.append(-current_number)
elif last_operation == '*':
stack.append(stack.pop() * current_number)
else:
stack.append(int(stack.pop() / current_number))
last_operation = character
current_number = 0
# Sum up the stack to get the final result.
result = 0
while stack:
result += stack.pop()
return result
Case | How to Handle |
---|---|
Empty or null input string | Return 0 immediately as there's nothing to calculate. |
String containing only whitespace | Return 0 as the expression is essentially empty. |
String with a single number | Return the number itself (after trimming whitespace). |
String starting or ending with an operator | Prepend '0+' to the string to handle the start and treat the end as incomplete, properly handling these operators. |
Consecutive operators or multiple spaces between numbers and operators | Filter out unnecessary spaces and handle consecutive operators based on precedence. |
Integer overflow during calculation | Use long type to prevent integer overflow during intermediate calculations and cast back to int for the final result. |
Division by zero | The problem description states integer division should truncate toward zero, implying division by zero won't occur but if it does, the environment will dictate the behavior (usually an exception or undefined result). |
Very long input string (performance) | Iterative solution avoids stack overflow issues of recursion, and with O(n) complexity based on string length provides linear performance. |