我试图写一个Java例程来计算数学表达式从字符串值,如:
"5 + 3" "10-4 * 5" "(1 + 10) * 3"
我想避免很多如果-then-else语句。 我该怎么做呢?
我试图写一个Java例程来计算数学表达式从字符串值,如:
"5 + 3" "10-4 * 5" "(1 + 10) * 3"
我想避免很多如果-then-else语句。 我该怎么做呢?
当前回答
解决这个问题的正确方法是使用词法分析器和解析器。您可以自己编写这些页面的简单版本,或者这些页面还包含指向Java词法分析器和解析器的链接。
创建递归下降解析器是非常好的学习练习。
其他回答
还有一个选择:https://github.com/stefanhaustein/expressionparser
我已经实现了一个简单而灵活的选项,以允许两者:
即时处理(Calculator.java, SetDemo.java) 构建和处理解析树(TreeBuilder.java)
上面链接的TreeBuilder是进行符号推导的CAS演示包的一部分。还有一个BASIC解释器的例子,我已经开始使用它来构建一个TypeScript解释器。
另一种方法是使用Spring表达式语言或SpEL,它在计算数学表达式时做了更多的工作,因此可能会有点过度。您不必使用Spring框架来使用这个表达式库,因为它是独立的。从SpEL文档中复制示例:
ExpressionParser parser = new SpelExpressionParser();
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); //24.0
像RHINO或NASHORN这样的外部库可以用来运行javascript。javascript可以计算简单的公式,而不需要对字符串进行分割。如果代码写得好,也不会对性能造成影响。 下面是一个使用RHINO -的示例
public class RhinoApp {
private String simpleAdd = "(12+13+2-2)*2+(12+13+2-2)*2";
public void runJavaScript() {
Context jsCx = Context.enter();
Context.getCurrentContext().setOptimizationLevel(-1);
ScriptableObject scope = jsCx.initStandardObjects();
Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
Context.exit();
System.out.println(result);
}
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class test2 {
public static void main(String[] args) throws ScriptException {
String s = "10+2";
ScriptEngineManager mn = new ScriptEngineManager();
ScriptEngine en = mn.getEngineByName("js");
Object result = en.eval(s);
System.out.println(result);
}
}
对于JDK1.6,您可以使用内置的Javascript引擎。
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
public class Test {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}