可以实现正数、负数、+、-、*、/、(、)的运算
class Solution {
public int calculate(String s) {
List<String> words = getInversePolishExpressions(handleSpacesAndNegativeNumber(s));
return calculateResult(words);
}
private int calculateResult(List<String> words) {
Stack<Integer> numbers = new Stack<>();
for (String word : words) {
if (isNumber(word.charAt(0))) {
numbers.push(Integer.parseInt(word));
} else {
int second = numbers.pop();
int first = numbers.pop();
int res;
switch (word) {
case "+":
res = first + second;
break;
case "-":
res = first - second;
break;
case "*":
res = first * second;
break;
case "/":
res = first / second;
break;
default:
res = -1;
break;
}
numbers.push(res);
}
}
return numbers.peek();
}
private String handleSpacesAndNegativeNumber(String s) {
s = s.replaceAll(" ", "");
char[] letters = s.toCharArray();
StringBuilder expression = new StringBuilder();
for (char letter : letters) {
if (letter == '+' || letter == '-') {
if (expression.length() < 1 || expression.charAt(expression.length() - 1) == '(') {
expression.append('0');
}
}
expression.append(letter);
}
return expression.toString();
}
private List<String> getInversePolishExpressions(String s) {
List<String> words = new ArrayList<>();
Stack<Character> operands = new Stack<>();
char[] letters = s.toCharArray();
operands.push('#');
int len = letters.length;
int i = 0;
while (i < len) {
if (isNumber(letters[i])) {
StringBuilder number = new StringBuilder();
while (i < len && isNumber(letters[i])) {
number.append(letters[i]);
i++;
}
words.add(number.toString());
} else {
if (letters[i] == '(') {
operands.push(letters[i]);
} else if (letters[i] == ')') {
while (!operands.empty() && operands.peek() != '(') {
words.add(operands.pop() + "");
}
operands.pop();
} else {
while (!operands.empty() && operands.peek() != '(' && getPriorityValue(letters[i]) <= getPriorityValue(operands.peek())) {
words.add(operands.pop() + "");
}
operands.push(letters[i]);
}
i++;
}
}
while (operands.peek() != '#') {
words.add(operands.pop() + "");
}
return words;
}
private int getPriorityValue(char c) {
switch (c) {
case '#':
return 0;
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return -1;
}
}
private boolean isNumber(char c) {
return c >= '0' && c <= '9';
}
}