原题网址:https://leetcode.com/problems/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
Note: Do not use the eval
built-in library function.
思路:由于涉及到括号,需要使用Stack(栈),即遇到开阔号入栈,遇到闭括号处理括号内未完成的计算。可惜写的代码比较罗嗦。
public class Solution {
public int calculate(String s) {
char[] sarray = s.toCharArray();
Expression[] expressions = new Expression[sarray.length];
int[] operands = new int[sarray.length];
int size = 0;
for(int i=0; i<sarray.length; i++) {
if (sarray[i] == ' ') continue;
if (sarray[i] >= '0' && sarray[i] <= '9') {
// 遇到数字
int num = (sarray[i] - '0');
while (i<sarray.length-1 && sarray[i+1] >= '0' && sarray[i+1] <= '9') num = num*10+(sarray[++i]-'0');
expressions[size] = Expression.OPERAND;
operands[size] = num;
size ++;
} else if (sarray[i] == '(') {
// 遇到括号
expressions[size++] = Expression.OPEN;
} else {
// 遇到右括号或加、减运算符号,需要将前面未完成的计算完成了
if (size >= 3) {
// 前面有未完成的计算
if (expressions[size-2] == Expression.PLUS) {
// 前面有未完成的加法
operands[size-3] += operands[size-1];
size -= 2;
} else if (expressions[size-2] == Expression.MINUS) {
// 前面有未完成的减法
operands[size-3] -= operands[size-1];
size -= 2;
}
}
if (sarray[i] == ')') {
// 匹配前面的开括号
expressions[size-2] = Expression.OPERAND;
operands[size-2] = operands[size-1];
size --;
} else if (sarray[i] == '+') {
// 遇到加号
expressions[size++] = Expression.PLUS;
} else {
// 遇到减号
expressions[size++] = Expression.MINUS;
}
}
}
if (size >= 3) {
// 检查是否有未完成的运算
if (expressions[size-2] == Expression.PLUS) {
operands[size-3] += operands[size-1];
size -= 2;
} else if (expressions[size-2] == Expression.MINUS) {
operands[size-3] -= operands[size-1];
size -= 2;
}
}
return operands[0];
}
}
enum Expression {OPERAND, OPEN, PLUS, MINUS};
时间复杂度O(N),空间复杂度O(N)。
性能还好:
下面是思路稍微不同的实现方式:
public class Solution {
public int calculate(String s) {
List<Expr> list = new ArrayList<>();
char[] sa = s.toCharArray();
for(int i=0; i<sa.length; i++) {
if (sa[i] == ' ') continue;
if (sa[i] >= '0' && sa[i] <= '9') {
int value = sa[i]-'0';
while (i<sa.length-1 && sa[i+1] >='0' && sa[i+1] <= '9') {
value *= 10;
value += sa[++i]-'0';
}
if (!list.isEmpty() && list.get(list.size()-1).type == Type.PLUS) {
list.remove(list.size()-1);
list.get(list.size()-1).value += value;
} else if (!list.isEmpty() && list.get(list.size()-1).type == Type.MINUS) {
list.remove(list.size()-1);
list.get(list.size()-1).value -= value;
} else {
list.add(new Expr(Type.OPERAND, value));
}
continue;
}
if (sa[i] == '(') {
list.add(new Expr(Type.LEFT));
continue;
}
if (sa[i] == ')') {
list.remove(list.size()-2);
if (list.size()>1 && list.get(list.size()-2).type == Type.PLUS) {
list.get(list.size()-3).value += list.get(list.size()-1).value;
list.remove(list.size()-1);
list.remove(list.size()-1);
} else if (list.size()>1 && list.get(list.size()-2).type == Type.MINUS) {
list.get(list.size()-3).value -= list.get(list.size()-1).value;
list.remove(list.size()-1);
list.remove(list.size()-1);
}
continue;
}
if (sa[i] == '+') {
list.add(new Expr(Type.PLUS));
continue;
}
if (sa[i] == '-') {
list.add(new Expr(Type.MINUS));
continue;
}
}
return list.get(0).value;
}
}
class Expr {
Type type;
int value;
Expr(Type type) {
this.type = type;
}
Expr(Type type, int value) {
this.type = type;
this.value = value;
}
}
enum Type {
OPERAND, PLUS, MINUS, LEFT
}