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;
        }
    }
}

All Problems

All Solutions