224. Basic Calculator && 227. Basic Calculator II

224. Basic Calculator

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

You may assume that the given expression is always valid.

Some examples:

"1 + 1" = 2
" 2-1 + 2 " = 3
"(1+(4+5+2)-3)+(6+8)" = 23
 

Solution 1:

class Solution {
  public int calculate(String s) {
    Stack<Integer> stack = new Stack<>();
    int result = 0;
    int num = 0;
    int sign = 1;
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      if (c == ' ')
        continue;
      if (Character.isDigit(c)) {
        num = 10 * num + c - '0';
        continue;
      }
      //when it's not a number
      if (c == '+') {
        result += sign * num;
        num = 0;
        sign = 1;
      } else if (c == '-') {
        result += sign * num;
        num = 0;
        sign = -1;
      } else if (c == '(') {
        //first push the result before (, then push the sign for (;
        stack.push(result);
        stack.push(sign);
        //reset the sign and result before entering new ()
        sign = 1;
        result = 0;
      } else if (c == ')') {
        result += sign * num;
        num = 0;
        result *= stack.pop();    //stack.pop() is the sign before the parenthesis
        result += stack.pop();   //stack.pop() now is the result calculated before the parenthesis
      }
    }
    return result + sign * num; //add the last number
  }
}

 

Solution 2:

public class Solution {
    public int calculate(String s) {
    ArrayDeque<String> numbers = new ArrayDeque<String>();
    ArrayDeque<Character> operators = new ArrayDeque<Character>();

    String number = "";
    for (Character c : s.toCharArray()) {
      if (c.equals(' ')) {
        number = resetNumber(number, numbers);
      } else if (c >= '0' && c <= '9') {
        number += c;
      } else if (c.equals('(')) {
        numbers.push("(");
        operators.push('('); //Difficulty part.
      } else if (c.equals(')')) {
        number = resetNumber(number, numbers);
        calculateToLeftParan(numbers, operators);
      } else if (c.equals('+') || c.equals('-')) {
        number = resetNumber(number, numbers);
        operators.push(c);
      }
    }

    if (!number.equals(""))
      numbers.push(number);

    while (!operators.isEmpty()) {
      Character op = operators.removeLast(); //remove from right
      Integer oprand1 = Integer.parseInt(numbers.removeLast());
      Integer oprand2 = Integer.parseInt(numbers.removeLast());

      if (op.equals('+')) {
        numbers.add(Integer.toString(oprand1 + oprand2));
      } else if (op.equals('-')) {
        numbers.add(Integer.toString(oprand1 - oprand2));
      }
    }

    if (numbers.isEmpty())
      return 0;
    return Integer.parseInt(numbers.pop());
  }

  private String resetNumber(String number, ArrayDeque<String> numbers) {
    if (!number.equals("")) {
      numbers.push(number);
      return "";
    } else
      return number;
  }

  private void calculateToLeftParan(ArrayDeque<String> numbers, ArrayDeque<Character> operators) {
    ArrayDeque<String> tmpNumbers = new ArrayDeque<String>();
    ArrayDeque<Character> tmpOperators = new ArrayDeque<Character>();
    String next;
    while (!(next = numbers.pop()).equals("("))
      tmpNumbers.push(next);
      
    if(operators.size()>0)
    {
        Character nextOp;
        while (!(nextOp = operators.pop()).equals('('))
          tmpOperators.push(nextOp);
    }
    numbers.push(doCalculate(tmpNumbers, tmpOperators));
  }

  private String doCalculate(ArrayDeque<String> numbersL2R, ArrayDeque<Character> operators) {
    while(numbersL2R.size() > 1) {
      Character op = operators.pop(); //remove from left
      Integer oprand1 = Integer.parseInt(numbersL2R.pop());
      Integer oprand2 = Integer.parseInt(numbersL2R.pop());

      if (op.equals('+')) {
        numbersL2R.push(Integer.toString(oprand1 + oprand2));
      } else if (op.equals('-')) {
        numbersL2R.push(Integer.toString(oprand1 - oprand2));
      }
    }
    return numbersL2R.pop();
  }
}

 

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.

You may assume that the given expression is always valid.

Some examples:

"3+2*2" = 7
" 3/2 " = 1
" 3+5 / 2 " = 5

  String

Solution1:
 Two stacks, one for numbers, one for +, - operators.
public class Solution {
  public int calculate(String s) {
    s = s.trim();
    Deque<Integer> numbers = new ArrayDeque<>();
    Deque<Character> operators = new ArrayDeque<>();

    int index = 0;
    while (index < s.length()) {
      while (s.charAt(index) == ' ')
        ++index;
      char c = s.charAt(index);
      if (c == '+' || c == '-' || c == '*' || c == '/') {
        operators.push(c);
        ++index;
      } else {
        int num = c - '0';
        ++index;
        while (index < s.length() && s.charAt(index) >= '0' && s.charAt(index) <= '9') {
          num = num * 10 + s.charAt(index) - '0';
          ++index;
        }
        if (operators.isEmpty()) {
          numbers.push(num);
          continue;
        }
        char prevOp = operators.peek();
        if (prevOp == '*' || prevOp == '/') {
          operators.pop();
          int prevNum = numbers.pop();
          if (prevOp == '*')
            numbers.push(prevNum * num);
          else
            numbers.push(prevNum / num);
        } else
          numbers.push(num);
      }
    }

    //MUST iterate through the operators from left to right!!!
    //e.g. 1-1+1
    while (!operators.isEmpty()) {
      char op = operators.removeLast();
      int firstNum = numbers.removeLast();
      int secondNum = numbers.removeLast();
      if (op == '+')
        numbers.add(firstNum + secondNum); //add() is addlast()
      else
        numbers.add(firstNum - secondNum);
    }
    return numbers.peek();
  }
}

 

Solution 2:

Only one stack, where all numbers will be summed up in the end.

public class Solution {
  public int calculate(String s) {
    s = s.trim(); //do trim to remove empty strings at the end.
    int len = s.length();
    if (len == 0)
      return 0;
    //this stack only keep numbers that will be summed in the end.
    Deque<Integer> stack = new ArrayDeque<>();

    int num = 0;
    char lastSign = '+';
    for (int i = 0; i < len; i++) {
      char c = s.charAt(i);
      if (c == ' ')
        continue;
      if (Character.isDigit(c)) {
        num = num * 10 + c - '0';
        if (i < len - 1)
          continue; //need to do calculation if at the end of string
      }

      if (lastSign == '-')
        stack.push(-num);
      else if (lastSign == '+')
        stack.push(num);
      else if (lastSign == '*')
        stack.push(stack.pop() * num);
      else //if (lastSign == '/')
        stack.push(stack.pop() / num);
      lastSign = c;
      num = 0;
    }

    int sum = 0;
    for (int i : stack)
      sum += i;
    return sum;
  }
}

 

 

 

 

 

 
posted @ 2016-04-27 13:42  新一代的天皇巨星  阅读(170)  评论(0)    收藏  举报