在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());
}
根据实际需要,有几个选项:
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)");
// Define "shortcuts"
engine.eval("var sin = Math.sin");
engine.eval("var PI = Math.PI");
// Actual expression to be evaluated
engine.eval("sin(PI)");
根据您实际想要做的事情,有几个选项:
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)");
// 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