在java中将math函数转换为javascript函数

在java中将math函数转换为javascript函数,java,regex,math,Java,Regex,Math,我制作了一个字符串数学表达式解析器,如下所示: public class ExpSolver { public String solve(String s){ try { ScriptEngineManager mgr = new ScriptEngineManager(); ScriptEngine engine = mgr.getEngineByName("JavaScript"); return engine.ev

我制作了一个字符串数学表达式解析器,如下所示:

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等。
要做到这一点,最好且代码高效的解决方案是什么?我见过regex表达式,但无法在如此大的范围内实现这一点。

JavaScript已经支持使用。您应该能够在正在计算的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");
}
staticmap replacements=newhashmap();
静止的{
替换。put(“sin”,“Math.sin”);
替换。放置(“cos”,“Math.cos”);
替换。放置(“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());
}
for(Map.Entry r:replacements.entrySet()){
//仅当希望将字符串解释为正则表达式时,才在此处使用replaceAll
s=s.replace(r.getKey(),r.getValue());
}

JavaScript已经使用支持这些函数。您应该能够在正在计算的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");
}
staticmap replacements=newhashmap();
静止的{
替换。put(“sin”,“Math.sin”);
替换。放置(“cos”,“Math.cos”);
替换。放置(“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());
}
for(Map.Entry r:replacements.entrySet()){
//仅当希望将字符串解释为正则表达式时,才在此处使用replaceAll
s=s.replace(r.getKey(),r.getValue());
}

根据实际需要,有几个选项:

  • 只需使用javascript内置的数学函数
    engine.eval("Math.sin(Math.PI)");
    
  • 构建自己的数学函数

    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)");
    
  • 执行上述任一操作,但对“用户”隐藏数学对象(或您自己的对象)

    为此,在javascript中,在全局范围内定义变量,这些变量包含对您希望具有语法快捷方式的函数(或常量)的引用

    // Define "shortcuts"
    engine.eval("var sin = Math.sin");  
    engine.eval("var PI = Math.PI");        
    // Actual expression to be evaluated    
    engine.eval("sin(PI)");
    

  • 根据您实际想要做的事情,有几个选项:

  • 只需使用javascript内置的数学函数
    engine.eval("Math.sin(Math.PI)");
    
  • 构建自己的数学函数

    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)");
    
  • 执行上述任一操作,但对“用户”隐藏数学对象(或您自己的对象)

    为此,在javascript中,在全局范围内定义变量,这些变量包含对您希望具有语法快捷方式的函数(或常量)的引用

    // Define "shortcuts"
    engine.eval("var sin = Math.sin");  
    engine.eval("var PI = Math.PI");        
    // Actual expression to be evaluated    
    engine.eval("sin(PI)");
    

  • 最后,我用下面的课程解决了这个问题:

    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;
    }
    }
    
    import java.util.logging.Level;
    导入java.util.logging.Logger;
    导入javax.script.ScriptEngine;
    导入javax.script.ScriptEngineManager;
    导入javax.script.ScriptException;
    /**
    *
    *@作者Aniruddha Sarkar(c)
    * sarkar4540@gmail.com
    */
    公共类ExpSolver{
    字符串[]regx;
    公共ExpSolver(){
    regx=新字符串[]{
    “Math.abs”,//a的绝对值
    “Math.acos”//a的弧余弦
    “Math.asin”,//a的弧正弦
    “Math.atan”,//a的反正切
    “Math.atan2”,//a/b的反正切
    “Math.ceil”,//最接近a且不小于a的整数
    “Math.cos”,//a的余弦
    “Math.exp”//a的指数(“Math.E的幂a)
    “Math.floor”,//最接近a的整数,不大于a
    “Math.log”,//基e的日志
    “Math.max”,//a和b的最大值
    “Math.min”,//a和b的最小值
    “Math.pow”//a到b的幂
    “Math.random”,//伪随机数0到1(参见示例)
    “Math.round”,//最接近a的整数(参见舍入示例)
    “Math.sin”//a的正弦
    “Math.sqrt”//a的平方根
    “Math.tan”//a的切线
    };
    }
    公共字符串求解(字符串s、字符串p){
    for(字符串str:regx){
    s=s.replaceAll(str.substring(str.indexOf(“.”+1),str);
    }
    int x;
    while(s!=null){
    x=s.indexOf('^');
    如果(x!=-1){
    StringBuilder xa=新的StringBuilder();
    对于(int i=x-1;i>=0;i--){
    chark=s.charAt(i);
    if(Character.isDigit(k)| | k=='。| | k=='E'){
    xa.附加(k);
    }
    如果(i>0),则为else
    如果(s.charAt(i-1)='E'){
    xa.附加(k);
    }
    否则{
    如果(k='-'){
    如果(i>0){
    int kdx=i-1;
    如果(kdx>0){
    char kt=s.charAt(kdx);
    if(!(Character.isDigit(kt)| | kt=='。){
    xa.附加(k);
    }
    }
    }
    否则{
    xa.附加(k);
    }
    }
    打破
    }
    }
    xa.reverse();
    StringBuilder xb=新的StringBuilder();
    附加(s.charAt(x+1));
    
    对于(inti=x+2;i,最后我用下面的类解决了这个问题:

    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;
    }
    }
    
    import java.util.logging.Level;
    导入java.util.logging.Logger;
    导入javax.script.ScriptEngine;
    导入javax.script.ScriptEngineManager;
    导入javax.script.ScriptException;
    /**
    *
    *@作者Aniruddha Sarkar(c)
    * sarkar4540@gmail.com
    */
    公共类ExpSolver{
    字符串[]regx;
    公共ExpSolver(){
    regx=n