二、运算处理
1.算术表达式处理
代码如下:
/**
* 算术表达式
*
* @param formula 计算表达式
* @return 计算结果
*/
public static BigDecimal execute(String formula, Map<String, String> evn) {
try {
String expr = formula
.replace("*", "*,")
.replace("/", "/,")
.replace("+", "+,")
.replace("-", "-,")
.replace("(", "(,")
.replace(")", "),");
String[] exprArr = expr.split("(?=[\\+\\-*/()])");
List<String> list = new ArrayList<>();
for (String x : exprArr) {
list.addAll(Arrays.asList(x.split(",")));
}
for (int i = 0; i < list.size(); i++) {
if (evn.containsKey(list.get(i))) {
list.set(i, evn.get(list.get(i)));
}
}
String[] in = new String[list.size()];
list.toArray(in);
return new ExprExecutor().expr(in, new AtomicInteger());
} catch (Exception ex) {
throw ex;
}
}
/**
* 表达式计算类
*/
static class ExprExecutor {
private static final char TEMPCHAR = 0;
public char lastsign1 = 0, lastsign2 = 0;
public BigDecimal temp1 = BigDecimal.ZERO, temp2 = BigDecimal.ZERO;
public BigDecimal expr(String[] in, AtomicInteger lastIndex) {
BigDecimal result = BigDecimal.ZERO;
String c;
boolean endLoop = false;
int index = 0;
while (index < in.length) {
c = in[index++];
switch (c) {
case ")":
case "]":
case "}":
lastIndex.set(index);
endLoop = true;
break;
case "(":
case "[":
case "{":
String[] t = Arrays.copyOfRange(in, index, in.length);
temp2 = new ExprExecutor().expr(t, lastIndex);
index += lastIndex.get();
break;
case "+":
case "-":
calcMultiply(TEMPCHAR);
result = calcSubtract(c.charAt(0), result);
break;
case "*":
case "/":
calcMultiply(c.charAt(0));
break;
default:
temp2 = new BigDecimal(c);
break;
}
if (endLoop) {
break;
}
}
calcMultiply(TEMPCHAR);
result = calcSubtract(TEMPCHAR, result);
return result;
}
private void calcMultiply(char c) {
switch (lastsign2) {
case 0:
temp1 = temp2;
break;
case '*':
temp1 = temp1.multiply(temp2);
break;
case '/':
temp1 = temp1.divide(temp2);
break;
default:
break;
}
temp2 = BigDecimal.ZERO;
lastsign2 = c;
}
private BigDecimal calcSubtract(char c, BigDecimal result) {
switch (lastsign1) {
case 0:
result = temp1;
break;
case '-':
result = result.subtract(temp1);
break;
case '+':
result = result.add(temp1);
break;
default:
break;
}
temp1 = BigDecimal.ZERO;
lastsign1 = c;
return result;
}
}
2.逻辑表达式处理
代码如下(>=、<=时值为数字存在问题):
/**
* 算术表达式
*
* @param formula 计算表达式
* @return 计算结果
*/
public static Boolean executeLogic(String formula, Map<String, String> evn) {
try {
String expr = formula
.replace("&&", ",&&,")
.replace("||", ",||,")
.replace("==", ",==,")
.replace("!=", ",!=,")
.replace(">=", ",>=,")
.replace("<=", ",<=,")
.replace("(", "(,")
.replace(")", ",)");
String[] exprArr = expr.split(",");
List<String> list = new ArrayList<>(Arrays.asList(exprArr));
for (int i = 0; i < list.size(); i++) {
if (evn.containsKey(list.get(i))) {
list.set(i, evn.get(list.get(i)));
}
}
String[] in = new String[list.size()];
list.toArray(in);
String expr1 = new ExprExecutorLogic().expr(in, new AtomicInteger());
return "true".equals(expr1);
} catch (Exception ex) {
throw ex;
}
}
/**
* 逻辑表达式处理类
*/
static class ExprExecutorLogic {
private static final String TEMPCHAR = "";
public String lastsign1 = "", lastsign2 = "";
public String temp1 = "";
public String temp2 = "";
public String expr(String[] in, AtomicInteger lastIndex) {
String result = null;
String c;
boolean endLoop = false;
int index = 0;
while (index < in.length) {
c = in[index++];
switch (c) {
case ")":
case "]":
case "}":
lastIndex.set(index);
endLoop = true;
break;
case "(":
case "[":
case "{":
String[] t = Arrays.copyOfRange(in, index, in.length);
temp2 = new ExprExecutorLogic().expr(t, lastIndex);
index += lastIndex.get();
break;
case "&&":
case "||":
calcMultiply(TEMPCHAR);
result = calcSubtract(c, result);
break;
case "==":
case "!=":
case ">=":
case "<=":
calcMultiply(c);
break;
default:
temp2 = c;
break;
}
if (endLoop) {
break;
}
}
calcMultiply(TEMPCHAR);
result = calcSubtract(TEMPCHAR, result);
return result;
}
private String calcSubtract(String c, String result) {
boolean tempResult = false;
if ("true".equals(result)) {
tempResult = true;
}
boolean temp1Bool = false;
if ("true".equals(temp1)) {
temp1Bool = true;
}
switch (lastsign1) {
case "":
result = temp1;
break;
case "&&":
result = String.valueOf(tempResult && temp1Bool);
break;
case "||":
result = String.valueOf(tempResult || temp1Bool);
break;
default:
break;
}
temp1 = "";
lastsign1 = c;
return result;
}
private void calcMultiply(String c) {
switch (lastsign2) {
case "":
temp1 = temp2;
break;
case "==":
temp1 = String.valueOf(temp1.equals(temp2));
break;
case "!=":
temp1 = String.valueOf(!temp1.equals(temp2));
break;
case ">=":
temp1 = String.valueOf(temp1.compareTo(temp2) >= 0);
break;
case "<=":
temp1 = String.valueOf(temp1.compareTo(temp2) <= 0);
break;
default:
break;
}
temp2 = "";
lastsign2 = c;
}
}