http://www.geeksforgeeks.org/expression-evaluation/
Mistakes
if ')', don't forget to peek at the top of operators to check whether it is '(' in the while condition
public class Solution {
/**
* @param expression: an array of strings;
* @return: an integer
*/
public int evaluateExpression(String[] expression) {
//two stacks, one is for operands, one is for operators
Stack<Integer> operands = new Stack<>();
Stack<Character> operators = new Stack<>();
//loop through each string in the input array,
for (String str : expression) {
char[] c = str.toCharArray();
//if numbers, push to value stack
if (c.length >= 2 || Character.isDigit(c[0])) {
operands.push(Integer.valueOf(str));
} else if (c[0] == '(') {
//if "(", push to stack
operators.push(c[0]);
} else if (c[0] == ')') {
//if ")", pop two operands, and one operator, do the operation, push result back to value stack, keep doing this until reach to "("
while (!operators.isEmpty() && operators.peek() != '(') {
char operator = operators.pop();
int num2 = operands.pop();
int num1 = operands.pop();
operands.push(calculate(operator, num1, num2));
}
operators.pop();
} else {
//if operators, if not empty and the top operator has equal or high prioity than this one, let prev operators do the operation with top two operands
if (operators.isEmpty() || hasPrecedence(c[0], operators.peek())) {
operators.push(c[0]);
} else {
char operator = operators.pop();
int num2 = operands.pop();
int num1 = operands.pop();
operands.push(calculate(operator, num1, num2));
operators.push(c[0]);
}
}
}
//loop throught the rest in two stacks
while (!operators.isEmpty()) {
char operator = operators.pop();
int num2 = operands.pop();
int num1 = operands.pop();
operands.push(calculate(operator, num1, num2));
}
//return result
return operands.isEmpty() ? 0 : operands.pop();
}
private int calculate(char operator, int operand1, int operand2){
int result = 0;
switch (operator) {
case '+':
result = operand1 + operand2;
break;
case '-':
result = operand1 - operand2;
break;
case '/':
result = operand1 / operand2;
break;
case '*':
result = operand1 * operand2;
break;
}
return result;
}
//return true, if operator1 is higher than opertor2
private boolean hasPrecedence(char operator1, char operator2) {
if (operator2 == '(' || operator2 == ')') {
return true;
}
if ((operator1 == '*' || operator1 == '/') && (operator2 == '+' || operator2 == '-')) {
return true;
}
return false;
}
};