我已经制作了一个String Mathematical表达式Parser,如下所示:
public class ExpSolver {
public String solve(String s){
try {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
return engine.eval(s).toString();
} catch (ScriptException ex) {
Logger.getLogger(ExpSolver.class.getName()).log(Level.SEVERE, null, ex);
}
return "0";
}
public static void main(String args[]){
System.out.println(new ExpSolver().solve(new java.util.Scanner(System.in).nextLine()));
}
}
现在我还想添加代码来解析我的程序中的sin,cos,tan,^(power),log等数学函数。 这样做的最佳和代码有效的解决方案是什么?我已经看过正则表达式但是我无法在如此大规模的情况下这样做。
答案 0 :(得分:2)
JavaScript已经使用Math object支持这些功能。您应该能够直接在您正在评估的JavaScript表达式中使用它。例如:
1 + Math.cos(2) * Math.pow(3,4)
如果您不想包含Math
前缀,可以在将字符串传递给解释器之前进行一些替换:
s = s.replace("sin", "Math.sin").replace("cos", "Math.cos")...
对于稍微清晰的代码,您可以将替换存储在地图中。在您的计划的顶层:
static Map<String, String> replacements = new HashMap<String, String>();
static {
replacements.put("sin", "Math.sin");
replacements.put("cos", "Math.cos");
replacements.put("tan", "Math.tan");
}
当你做替换时:
for (Map.Entry<String, String> r : replacements.entrySet()) {
// Use replaceAll here only if you want the Strings to be interpreted as regexes
s = s.replace(r.getKey(), r.getValue());
}
答案 1 :(得分:2)
有几个选项,具体取决于您实际想要做的事情:
engine.eval("Math.sin(Math.PI)");
建立自己的数学函数
public class MyMathObject {
public Double doSomeMath(Double a, Double b) {
return a*b;
}
}
// Create an instance of your math object and add it to the engine
MyMathObject myMathObject = new MyMathObject();
engine.put("funkyMath", myMathObject);
// Go ahead and use it
engine.eval("funkyMath.doSomeMath(3.14159, 2)");
执行上述任一操作,但隐藏“用户”中的Math对象(或您自己的对象)。
为此,在javascript中,在全局范围内定义变量,这些变量包含对期望具有语法快捷方式的函数(或常量)的引用。
// Define "shortcuts"
engine.eval("var sin = Math.sin");
engine.eval("var PI = Math.PI");
// Actual expression to be evaluated
engine.eval("sin(PI)");
答案 2 :(得分:1)
如何使用math.js的表达式解析器并通过Java ScriptEngine使用它?
这是一个例子:
package org.mathjs;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class MathJSDemo {
protected static String MATHJS_URL =
"http://cdnjs.cloudflare.com/ajax/libs/mathjs/1.0.1/math.js";
protected ScriptEngine engine;
public MathJSDemo() throws MalformedURLException, ScriptException, IOException {
ScriptEngineManager manager = new ScriptEngineManager ();
engine = manager.getEngineByName ("js");
engine.eval(new InputStreamReader(new URL(MATHJS_URL).openStream()));
engine.eval("var parser = math.parser();");
engine.eval("var precision = 14;");
}
public String eval (String expr) throws ScriptException {
String script = "math.format(parser.eval('" + expr + "'), precision);";
return (String) engine.eval(script);
}
public static void main(String[] args) throws ScriptException, MalformedURLException, IOException {
MathJSUrl math = new MathJSDemo();
System.out.println(math.eval("a = 4.5"));
System.out.println(math.eval("1.2 * (2 + a)"));
System.out.println(math.eval("5.08 cm in inch"));
System.out.println(math.eval("sin(45 deg) ^ 2"));
System.out.println(math.eval("9 / 3 + 2i"));
System.out.println(math.eval("det([-1, 2; 3, 1])"));
}
}
答案 3 :(得分:0)
最后我用下面的课解决了这个问题:
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
/**
*
* @author Aniruddha Sarkar(c)
* sarkar4540@gmail.com
*/
public class ExpSolver {
String[] regx;
public ExpSolver() {
regx=new String[]{
"Math.abs", // the absolute value of a
"Math.acos", // arc cosine of a
"Math.asin", // arc sine of a
"Math.atan", // arc tangent of a
"Math.atan2", // arc tangent of a/b
"Math.ceil", // integer closest to a and not less than a
"Math.cos", // cosine of a
"Math.exp", // exponent of a ("Math.E to the power a)
"Math.floor", // integer closest to a, not greater than a
"Math.log", // log of a base e
"Math.max", // the maximum of a and b
"Math.min", // the minimum of a and b
"Math.pow", // a to the power b
"Math.random", // pseudorandom number 0 to 1 (see examples)
"Math.round", // integer closest to a (see rounding examples)
"Math.sin", // sine of a
"Math.sqrt", // square root of a
"Math.tan" // tangent of a
};
}
public String solve(String s,String p){
for(String str:regx){
s=s.replaceAll(str.substring(str.indexOf(".")+1), str);
}
int x;
while(s!=null){
x=s.indexOf('^');
if(x!=-1){
StringBuilder xa=new StringBuilder();
for(int i=x-1;i>=0;i--){
char k=s.charAt(i);
if(Character.isDigit(k)||k=='.'||k=='E'){
xa.append(k);
}
else if(i>0)
if(s.charAt(i-1)=='E'){
xa.append(k);
}
else{
if(k=='-'){
if(i>0){
int kdx=i-1;
if(kdx>0){
char kt=s.charAt(kdx);
if(!(Character.isDigit(kt)||kt=='.')){
xa.append(k);
}
}
}
else{
xa.append(k);
}
}
break;
}
}
xa.reverse();
StringBuilder xb=new StringBuilder();
xb.append(s.charAt(x+1));
for(int i=x+2;i<s.length();i++){
char k=s.charAt(i);
if(Character.isDigit(k)||k=='.'||k=='E'||s.charAt(i-1)=='E'){
xb.append(k);
}
else{
break;
}
}
double a=Double.parseDouble(xa.toString()),b=Double.parseDouble(xb.toString());
double r=Math.pow(a,b);
s=s.substring(0,x-xa.length())+((int)r==r?(int)r:r)+s.substring(x+xb.length()+1,s.length());
continue;
}
break;
}
try {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
engine.put("x", Double.parseDouble(p));
return round(Double.parseDouble(engine.eval(s).toString()))+"";
} catch (ScriptException ex) {
Logger.getLogger(ExpSolver.class.getName()).log(Level.SEVERE, null, ex);
}
return "0";
}
public static void main(String args[]){
System.out.println(new ExpSolver().solve(new java.util.Scanner(System.in).nextLine(),"25"));
}
public static float round(double x){
return ((float)Math.rint((x-0.05)*100))/100;
}
}