Question
Formatted question description: https://leetcode.ca/all/227.html
227. Basic Calculator II
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +, -, *, / operators and empty spaces .
The integer division should truncate toward zero.
Example 1:
Input: "3+2*2"
Output: 7
Example 2:
Input: " 3/2 "
Output: 1
Example 3:
Input: " 3+5 / 2 "
Output: 5
Note:
You may assume that the given expression is always valid.
Do not use the eval built-in library function.
@tag-stack
Algorithm
Due to the operational priority, the measure we took is to use a stack to store the numbers
- If the sign before the number is addition or subtraction, then push the current number onto the stack. Note that if it is a minus sign, add the opposite number of the current number, because subtraction is equivalent to adding an opposite number.
- If the previous symbol is multiplication or division, then take a number from the top of the stack and the current number for multiplication or division, and then push the result onto the stack.
Then after completing the traversal, all the multiplications or divisions are completed, and all the numbers in the stack are added up to get the final result.
Code
Java
import java.util.Stack;
public class Basic_Calculator_II {
class Solution {
// possible overflow
public int calculate(String s) {
if (s == null || s.length() == 0) {
return 0;
}
Stack<Integer> sk = new Stack<>();
// always cache prev number and operator, if * or /, then compute result
char prevOperator = '+';
int prevNumber = 0;
// 3+2*4+5
for (int i = 0; i < s.length(); i++) {
char current = s.charAt(i);
if (current >= '0' && current <= '9') { // parse value
// it's a digit
prevNumber = prevNumber * 10 + (current - '0');
}
// find an operator, so check this operator's prev number and prev number's operator
if ((current < '0' && current != ' ') || i == s.length() - 1) {
// it's a operator
if (prevOperator == '+') { // @note: key is compare prev operator, not current operator
sk.push(prevNumber);
} else if (prevOperator == '-') {
sk.push(-1 * prevNumber);
} else if (prevOperator == '*' || prevOperator == '/') {
int tmp = (prevOperator == '*') ? sk.peek() * prevNumber : sk.peek() / prevNumber;
sk.pop();
sk.push(tmp);
} // else skip space
prevOperator = current;
prevNumber = 0; // if an operator triggering a calculation, reset prevNumber, because result pushed to stack already
}
}
int result = 0;
while (!sk.empty()) { // before while, all vals in stack to be added. no * or /
result += sk.peek();
sk.pop();
}
return result;
}
}
}