Java 引入js加减乘除表达式求值算法
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JSUtils {
private static final Pattern EXPRESSION_PATTERN = Pattern.compile("[0-9\\.+-/*()= ]+");
private static final Map<String, Integer> OPT_PRIORITY_MAP = new HashMap<String, Integer>() {
private static final long serialVersionUID = 6968472606692771458L;
{
put("(", 0);
put("+", 2);
put("-", 2);
put("*", 3);
put("/", 3);
put(")", 7);
put("=", 20);
}
};
public static double executeExpression(String expression) {
if (null == expression || "".equals(expression.trim())) {
throw new IllegalArgumentException("表达式不能为空!");
}
Matcher matcher = EXPRESSION_PATTERN.matcher(expression);
if (!matcher.matches()) {
throw new IllegalArgumentException("表达式含有非法字符!");
}
Stack<String> optStack = new Stack<>();
Stack<BigDecimal> numStack = new Stack<>();
StringBuilder curNumBuilder = new StringBuilder(16);
for (int i = 0; i < expression.length(); i++) {
char c = expression.charAt(i);
if (c != ' ') {
if ((c >= '0' && c <= '9') || c == '.') {
curNumBuilder.append(c);
} else {
if (curNumBuilder.length() > 0) {
numStack.push(new BigDecimal(curNumBuilder.toString()));
curNumBuilder.delete(0, curNumBuilder.length());
}
String curOpt = String.valueOf(c);
if (optStack.empty()) {
optStack.push(curOpt);
} else {
if (curOpt.equals("(")) {
optStack.push(curOpt);
} else if (curOpt.equals(")")) {
directCalc(optStack, numStack, true);
} else if (curOpt.equals("=")) {
directCalc(optStack, numStack, false);
return numStack.pop().doubleValue();
} else {
compareAndCalc(optStack, numStack, curOpt);
}
}
}
}
}
if (curNumBuilder.length() > 0) {
numStack.push(new BigDecimal(curNumBuilder.toString()));
}
directCalc(optStack, numStack, false);
return numStack.pop().doubleValue();
}
public static void compareAndCalc(Stack<String> optStack, Stack<BigDecimal> numStack,
String curOpt) {
String peekOpt = optStack.peek();
int priority = getPriority(peekOpt, curOpt);
if (priority == -1 || priority == 0) {
String opt = optStack.pop();
BigDecimal num2 = numStack.pop();
BigDecimal num1 = numStack.pop();
BigDecimal bigDecimal = floatingPointCalc(opt, num1, num2);
numStack.push(bigDecimal);
if (optStack.empty()) {
optStack.push(curOpt);
} else {
compareAndCalc(optStack, numStack, curOpt);
}
} else {
optStack.push(curOpt);
}
}
public static void directCalc(Stack<String> optStack, Stack<BigDecimal> numStack,
boolean isBracket) {
String opt = optStack.pop();
BigDecimal num2 = numStack.pop();
BigDecimal num1 = numStack.pop();
BigDecimal bigDecimal = floatingPointCalc(opt, num1, num2);
numStack.push(bigDecimal);
if (isBracket) {
if ("(".equals(optStack.peek())) {
optStack.pop();
} else {
directCalc(optStack, numStack, isBracket);
}
} else {
if (!optStack.empty()) {
directCalc(optStack, numStack, isBracket);
}
}
}
public static BigDecimal floatingPointCalc(String opt, BigDecimal bigDecimal1,
BigDecimal bigDecimal2) {
BigDecimal resultBigDecimal = new BigDecimal(0);
switch (opt) {
case "+":
resultBigDecimal = bigDecimal1.add(bigDecimal2);
break;
case "-":
resultBigDecimal = bigDecimal1.subtract(bigDecimal2);
break;
case "*":
resultBigDecimal = bigDecimal1.multiply(bigDecimal2);
break;
case "/":
resultBigDecimal = bigDecimal1.divide(bigDecimal2, 10, BigDecimal.ROUND_HALF_DOWN);
break;
default:
break;
}
return resultBigDecimal;
}
public static int getPriority(String opt1, String opt2) {
int priority = OPT_PRIORITY_MAP.get(opt2) - OPT_PRIORITY_MAP.get(opt1);
return priority;
}
private static boolean isDoubleEquals(double value1, double value2) {
System.out.println("正确结果=" + value1 + ", 实际计算结果=" + value2);
return Math.abs(value1 - value2) <= 0.0001;
}
public static void main(String[] args) throws ScriptException {
Scanner in = new Scanner(System.in);
System.out.println("请输入一个算法表达式:");
String str = in.next();
Matcher matcher = EXPRESSION_PATTERN.matcher(str);
if (!matcher.matches()) {
System.out.println("aaaaa");
return;
}
ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
Object eval = se.eval(str);
Double aDouble = Double.valueOf(eval.toString());
BigDecimal b = new BigDecimal(aDouble);
double doubleRate = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
str +="=";
double aa = executeExpression(str);
System.out.println("js算:"+doubleRate+"---算法:"+aa);
}
}
引入js
ScriptEngine se = new ScriptEngineManager().getEngineByName("JavaScript");
Object eval = se.eval("1+2+(1*3)");
Double aDouble = Double.valueOf(eval.toString());
DecimalFormat df = new DecimalFormat("0.00");
String amountstr = df.format(aDouble);
amount = new BigDecimal(amountstr);