java的代数方程解析器

我需要一个库来解析方程式,给出结果给出输入。

例如这样的事情:

String equation = "x + y + z"; Map vars = new HashMap(); vars.add("x", 2); vars.add("y", 1), vars.add("z", 3); EquationSolver solver = new EquationSolver(equation, vars); int result = solver.getResult(); System.out.println("result: " + result); 

并评估为:6

是否有任何类型的java库可以为我做到这一点?

谢谢

您可以使用Java 1.6的脚本function:

 import javax.script.*; import java.util.*; public class Main { public static void main(String[] args) throws Exception { ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); Map vars = new HashMap(); vars.put("x", 2); vars.put("y", 1); vars.put("z", 3); System.out.println("result = "+engine.eval("x + y + z", new SimpleBindings(vars))); } } 

产生:

 result = 6.0 

对于更复杂的表达式, JEP是一个不错的选择。

还有exp4j ,一个基于Dijkstra的Shunting Yard的表达式评估器。 它在Apache License 2.0下免费提供并可再发行,大小仅为25kb,非常易于使用。

 Calculable calc = new ExpressionBuilder("3 * sin(y) - 2 / (x - 2)") .withVariable("x", varX) .withVariable("y", varY) .build() double result1=calc.calculate(); 

还有一个在exp4j中使用自定义函数的工具 。

exp4j – 评估数学表达式

玩的开心!

如果你想要高性能,我建议不要使用exp4j,因为CogitoLearning类比exp4j快了大约2600倍(在1万次迭代上测试),是的你读得对。

通常,简单表达式足以满足业务应用程序的需要。 因此,CogitoLearning创建的库可能是更好的选择。

基准测试结果:

 1000000 iterations to evaluate 200*(1+(pi/2))^2 Time Exp4J: 1.041117999977863E-5 Time JavaScript:4.532046999924487E-5 - 0.2297235664138545x slower than Exp4j Time ExpCogit: 4.0000000000000036E-9 - 2602.794999944655x faster than Exp4j 

有关Cogito库的信息,请参阅http://cogitolearning.co.uk/docs/cogpar/index.html

请注意:测试用例并不完全纯粹用于评估JavaScript性能,因为我没有使用预构建表达式来处理该情况。

使用的基准代码:

 public class TestParser { private static String exprStr = "200*(1+(pi/2))^2"; /** * Exp4j */ private static ExpressionBuilder eb = new ExpressionBuilder(exprStr); /** * Cogit */ private static Parser parser = new Parser(); private static ExpressionNode expr = parser.parse(exprStr); /** * JavaScript */ private static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript"); private static Map vars = new HashMap(); public static void main(String[] args) throws UnknownFunctionException, UnparsableExpressionException, ScriptException { int n = 1000000; double t1 = 0d; for(int i=1; i!=n; i++) { t1+=getCalcTimeExp4J(); } double r1=t1/n; double t2 = 0d; for(int i=1; i!=n; i++) { t2+=getCalcTimeCogit(); } double r2=t2/n; double t3 = 0d; for(int i=1; i!=n; i++) { t3+=getCalcTimeJavaScriptEngine(); } double r3=t3/n; System.out.println(n + " iterations to evaluate " + exprStr); System.out.println("Time Exp4J:\t" + r1); System.out.println("Time JavaScript:" + r3 + " - " + r1/r3 + "x slower than Exp4j"); System.out.println("Time ExpCogit:\t" + r2 + " - " + r1/r2 + "x faster than Exp4j"); } private static double getCalcTimeJavaScriptEngine() throws ScriptException { long t = Util.nanotime(); vars.put("pi", Math.PI); //Note that we're actually not using a pre-build expression here. engine.eval(exprStr, new SimpleBindings(vars)); return(Util.nanotimeToSeconds(t)); } private static double getCalcTimeCogit() { long t = Util.nanotime(); expr.accept(new SetVariable("pi", Math.PI)); double r = expr.getValue(); return(Util.nanotimeToSeconds(t)); } private static double getCalcTimeExp4J() throws UnknownFunctionException, UnparsableExpressionException { long t = Util.nanotime(); Calculable calc = eb.withVariable("pi", Math.PI).build(); double r = calc.calculate(); return(Util.nanotimeToSeconds(t)); } } 

试试mXparser ,下面你会看到用法示例:

 import org.mariuszgromada.math.mxparser.*; ... ... String equation = "x + y + z"; Argument x = new Argument("x = 2"); Argument y = new Argument("y = 1"); Argument z = new Argument("z = 3"); Expression solver = new Expression(equation, x, y, z); double result1 = solver.calculate(); System.out.println("result 1: " + result1); x.setArgumentValue(3); y.setArgumentValue(4); z.setArgumentValue(5); double result2 = solver.calculate(); System.out.println("result 2: " + result2); 

结果:

 result 1: 6.0 result 2: 12.0 

这里mXparser的优点是mXparser只预编译一次表达式,然后,在参数值改变之后,计算速度非常快。

按照mXparser教程 , mXparser数学集合 , mXparser API 。

问候