实现一个基本的计算器来计算一个简单的字符串表达式的值。
字符串表达式可以包含左括号 ( ,右括号 ),加号 + ,减号 -,非负整数和空格 。
示例 1:
输入: “1 + 1”
输出: 2
示例 2:
输入: " 2-1 + 2 "
输出: 3
示例 3:
输入: “(1+(4+5+2)-3)+(6+8)”
输出: 23
说明:
你可以假设所给定的表达式都是有效的。
请不要使用内置的库函数 eval。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/basic-calculator
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/**
* https://leetcode-cn.com/problems/basic-calculator/
* 224. 基本计算器
* ☆☆☆☆
* keyword:数学,计算器,逆波兰表达式
* ————————————————————————————————————————————————————————————————————————————
* 相关题目:
* 150. 逆波兰表达式求值
* {@link org.alphacat.leetcode.solution.mid.no1to1000.No150_evalRPN}
*
*
* ————————————————————————————————————————————————————————————————————————————
*/
public class No224_calculate {
private final static char SPACE = ' ';
private final static char CHAR_LEFT_BRACKET = '(';
private final static char RIGHT_BRACKET = ')';
private final static char PLUS = '+';
private final static char MINUS = '-';
private final static char MULTIPLY = '*';
private final static char DIVIDE = '/';
private final static String LEFT_BRACKET = "(";
private final static String STING_PLUS = "+";
private final static String STING_MINUS = "-";
private final static String STING_MULTIPLY = "*";
private final static String STING_DIVIDE = "/";
public int calculate(String s) {
String[] reversePolish = getReversePolish(s);
return evalRPN(reversePolish);
}
private String[] getReversePolish(String s) {
List<String> res = new ArrayList<>();
Stack<String> stack = new Stack<>();
char[] array = s.toCharArray();
int n = array.length;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (c == SPACE) {
continue;
}
if (Character.isDigit(c)) {
sb.append(c);
continue;
}
if (sb.length() > 0) {
res.add(sb.toString());
sb.delete(0, sb.length());
}
if (isOperation(c)) {
while (!stack.isEmpty()) {
String peak = stack.peek();
if (peak.equals(LEFT_BRACKET)) {
break;
}
res.add(stack.pop());
}
stack.push(String.valueOf(c));
continue;
}
if (c == CHAR_LEFT_BRACKET) {
stack.push(String.valueOf(c));
} else if (c == RIGHT_BRACKET) {
while (!stack.isEmpty()) {
String peak = stack.peek();
if (peak.equals(LEFT_BRACKET)) {
break;
}
res.add(stack.pop());
}
//左括号出栈
stack.pop();
}
}
if (sb.length() > 0) {
res.add(sb.toString());
}
while (!stack.isEmpty()) {
res.add(stack.pop());
}
return ListToStringArr(res);
}
private boolean isOperation(char s) {
if (s == PLUS) {
return true;
}
if (s == MINUS) {
return true;
}
if (s == MULTIPLY) {
return true;
}
return s == DIVIDE;
}
private String[] ListToStringArr(List<String> list) {
return list.toArray(new String[list.size()]);
}
public int evalRPN(String[] tokens) {
Stack<Integer> stack = new Stack<>();
for (String token : tokens) {
if (!isOperation(token)) {
Integer num = Integer.valueOf(token);
stack.add(num);
} else {
int num2 = stack.pop();
int num1 = stack.pop();
int res = calculate(num1, num2, token);
stack.add(res);
}
}
return stack.pop();
}
private int calculate(int num1, int num2, String operation) {
if (operation.equals(STING_PLUS)) {
return num1 + num2;
}
if (operation.equals(STING_MINUS)) {
return num1 - num2;
}
if (operation.equals(STING_MULTIPLY)) {
return num1 * num2;
}
return num1 / num2;
}
private boolean isOperation(String s) {
if (s.equals(STING_PLUS)) {
return true;
}
if (s.equals(STING_MINUS)) {
return true;
}
if (s.equals(STING_MULTIPLY)) {
return true;
}
return s.equals(STING_DIVIDE);
}
}
public int calculate_2(String s) {
int operand = 0;
int digitCount = 0;
int n = s.length();
Stack<Object> stack = new Stack<>();
for (int i = n - 1; i >= 0; i--) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
int num = c - '0';
operand = (int) Math.pow(10, digitCount) * num + operand;
++digitCount;
continue;
}
if (c == SPACE) {
continue;
}
if (digitCount != 0) {
stack.push(operand);
digitCount = 0;
operand = 0;
}
if (c == LEFT_BRACKET) {
evaluate(stack);
} else {
stack.push(c);
}
}
if (digitCount != 0) {
stack.push(operand);
}
return evaluate(stack);
}
public int evaluate(Stack<Object> stack) {
int res = 0;
if (!stack.empty()) {
res = (int) stack.pop();
}
while (!stack.empty()) {
char sign = (char) stack.pop();
if (sign == RIGHT_BRACKET) {
break;
}
if (sign == '+') {
res += (int) stack.pop();
} else {
res -= (int) stack.pop();
}
}
stack.push(res);
return res;
}
private final static char SPACE = ' ';
private final static char LEFT_BRACKET = '(';
private final static char RIGHT_BRACKET = ')';
private final static char PLUS = '+';
private final static char MINUS = '-';
private final static int POSITIVE = 1;
private final static int NEGATIVE = -1;
public int calculate(String s) {
Stack<Integer> stack = new Stack<>();
int operand = 0;
int sign = POSITIVE;
int ans = 0;
for (int i = 0; i < s.length(); ++i) {
char c = s.charAt(i);
if (Character.isDigit(c)) {
operand = operand * 10 + c - '0';
} else if (c == PLUS) {
ans += sign * operand;
sign = POSITIVE;
operand = 0;
} else if (c == MINUS) {
ans += sign * operand;
sign = NEGATIVE;
operand = 0;
} else if (c == LEFT_BRACKET) {
stack.push(ans);
stack.push(sign);
sign = POSITIVE;
ans = 0;
} else if (c == RIGHT_BRACKET) {
ans += sign * operand;
ans *= stack.pop();
ans += stack.pop();
operand = 0;
}
}
return ans + operand * sign;
}