一个循环,没有栈,没有递归。逻辑有点绕,所以没什么注释。(带括号算式)
(阿里开发手册提到:不要用异常来处理业务,异常抛出耗时的问题。这里为了拿到错误信息就用了异常,不需要异常信息返回null即可)
/**
* 计算无括号算式,如 1+2*5-8 。只返回null或double。算式异常时返回null
* @author: 一只拖拉机
* @param a
* @exception ExpressionException :表达式错误异常
* @exception NumberFormatException 除数0、数字转化异常
* @return
* @version
*/
private static Double computeNumber(String a) {
if(a == null)return null;
char[] chars = a.toCharArray();
Double tem = null,m1=null;
int f=0;
char ty = 0,f1=0,f2=0; // 1+ 2- 3 * 4/
for(int i=0;i<chars.length;i++) {
char t = chars[i];
if(t<42 || t== 44 || t > 57)throw new ExpressionException("出现了不应该出现的字符:"+t);; // 只允许的符号 0至9 + - . / *
if(t < 48 && t != 46 && i > 0 && chars[i-1] > 47 && chars[i-1] < 58) { // + - * /
if(t=='-' || t=='+') {
if(m1 != null) {
Double ddd= Double.valueOf(String.valueOf(chars, f, i-f));
if(f1 > 0) {
tem = computeNormal(f1,tem,computeNormal(f2,m1,ddd));
}else {
tem = computeNormal(f2,m1,ddd);
}
m1 = null;
}else if(f1=='-') {
tem =tem - Double.valueOf(String.valueOf(chars, f, i-f));
}else if (f1 == '+') {
tem = tem + Double.valueOf(String.valueOf(chars, f, i-f));
}else { // 首次
tem = Double.valueOf(String.valueOf(chars, f, i-f));
}
f1 = t;
}else {
if(m1 != null) {
m1 = computeNormal(f2,m1,Double.valueOf(String.valueOf(chars, f, i-f)));
}else {
m1 = Double.valueOf(String.valueOf(chars, f, i-f));
}
f2 = t;
}
ty = t;
f = i + 1;
}
if(i == chars.length-1) {
if(i-f+1 == 0) throw new ExpressionException("错误的表达式:"+chars[i]); // 表示最后一个是字符
Double ddd= Double.valueOf(String.valueOf(chars, f, i-f+1));
if(f == 0)return ddd;
if(m1 != null) {
if(f1 > 0) {
return computeNormal(f1,tem,computeNormal(f2,m1,ddd));
}
return computeNormal(f2,m1,ddd);
}
return computeNormal(ty,tem,ddd);
}
}
throw new ExpressionException("错误的表达式");
}
private static Double computeNormal(char sign,Double d1,Double d2) {
if(d1==null || d2== null)return null;
switch(sign) {
case '-':
return d1 - d2;
case '+':
return d1 + d2;
case '*':
return d1 * d2;
case '/':
if(d2 == 0)throw new NumberFormatException("除数不能为0");
return d1 / d2;
default :
return null;
}
}