题解 | #正则表达式匹配#递归+栈
表达式求值
http://www.nowcoder.com/practice/c215ba61c8b1443b996351df929dc4d4
用递归结合没有括号的做法
public int solve(String s) {
if (s == null || s.length() == 0) return 0;
return calc(s.toCharArray(), 0)[0];
}
//计算idx到)或者结尾的表达式的值,返回值中0:表达式的值,1:接着从哪个下标开始
public int[] calc(char[] strs, int idx) {
Stack<Integer> stack = new Stack<>();
//每次处理一对值,+3,-2,这样一对一对的处理,保证栈里只有值,而且之后栈中的值只做加法,妙啊
int N = strs.length;
int i = idx;
int num = 0;
char preSign = '+';
//考虑(1+2),以)结尾这种情况怎么处理?
//考虑1+5,这最后一个数怎么收集?
//将处理一对的逻辑抽离成方法,这个方法由出现新运算符和结尾进行触发
for (; i < N && strs[i] != ')'; i++) {
if (Character.isDigit(strs[i])) {
num = num * 10 + (strs[i] - '0');
} else if (strs[i] == '(') {
//一对一对,处理,所以,碰到下一个非数字的时候处理前一对,此时num是第二个运算数
//就算是+3这种情况,也就是此时第一个+进行结算的时候其实前面没有数的,将num=0压入也不会影响结果
//这相当于如果表达式开头是运算符,那么就给它添个0,比如-3+5-->0-3+5,结果依然正确
int[] inRes = calc(strs, i + 1);
i = inRes[1];
num = inRes[0];
} else {
resolvePair(stack, preSign, num);
num = 0;
preSign = strs[i];
}
}
resolvePair(stack, preSign, num);//收集最后一个数
int res = 0;
while (!stack.isEmpty()) {//栈中剩下都是做加法了
res += stack.pop();
}
return new int[]{res, i};
}
public void resolvePair(Stack<Integer> stack, char preSign, int num) {
switch (preSign) {
case '+':
stack.push(num);
break;
case '-':
stack.push(-num);
break;
default:
stack.push(stack.pop() * num);
}
}
360集团公司氛围 395人发布