我有一个带有数学运算符的字符串,我需要将其转换为int
(答案)。
下面的代码不起作用,但我不确定如何让 answer 变量起作用。
String question;
int answer;
question = "7/7+9-9*5/5";
answer = Integer.parseInt(question);
Integer.parseInt(question);
……要是这么简单就好了……
您有一个"7/7+9-9*5/5"
中缀符号的数学表达式,您想要评估并将结果打印给用户。做到这一点的方法是使用Shutting-yard 算法将其转换为后缀表示法,也称为反向波兰表示法。将表达式转换为后缀评估后,使用此算法非常容易
public class MainTest {
public static void main(String[] args)throws Exception {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval("7/7+9-9*5/5");
System.out.println(result);
}
}
a) 将字符串编译成 Java 类
b) 使用自定义 ClassLoader 加载类。
c) 使用反射执行它。
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
public class MainTest{
public static void eval(String str) throws Exception{
StringBuffer sb = new StringBuffer();
sb.append("public class TempClass{\n");
sb.append(" public void run(){\n");
sb.append(" " + str + "\n");
sb.append(" }\n");
sb.append("}\n");
System.out.println(sb.toString());
Class clazz = new EvalClassLoader().findClass(sb.toString());
Method method = clazz.getMethod("run");
method.invoke(clazz.newInstance());
}
public static void main(String[] args) throws Exception {
eval("System.out.println(7/7+9-9*5/5);");
}
}
/**
* A custom class Loader.
*/
class EvalClassLoader extends ClassLoader{
private String tempCLassName = "TempClass";
@Override
protected Class<?> findClass(String codeStr) throws ClassNotFoundException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
JavaFileObject file = new ClassFromString(tempCLassName, codeStr.toString());
// Start a compile task
Iterable<JavaFileObject> compilationUnits = Arrays.asList(file);
JavaCompiler.CompilationTask task = compiler
.getTask(null, null, null, null, null, compilationUnits);
if(task.call()){
return loadClass(tempCLassName);
}
return null;
}
}
/**
* A Java class constructed from String.
*/
class ClassFromString extends SimpleJavaFileObject{
private String code;
public ClassFromString(String className,String code){
super(URI.create("string:///" + className.replace('.', '/') +
Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors)
throws IOException {
return code;
}
}
从 1.6 开始,Java 已经嵌入了 JavaScript 引擎
ScriptEngine e = new ScriptEngineManager().getEngineByName("js");
int res = ((Number)e.eval("7/7+9-9*5/5")).intValue();
你需要像Reverse Polish notation这样的东西。理解该算法并将其移植到 Java 大约需要一天的时间。当然,您可以在 Google 上搜索代码,但我强烈建议您学习该 wiki 页面。
我会让框架和其他库为我完成工作。如果这是学术问题,我建议使用 Lai Vung 提供的解决方案。使用将为您进行解析和计算的 ScriptManager,然后将输出转换为所需的类型。快速演示:
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class Main {
public static void main(String[] args) throws ScriptException {
String question;
int answer;
question = "7/7+9-9*5/5";
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
answer = ((Number)engine.eval(question)).intValue();
}
}
值得一提的是:如果 android 不提供对脚本引擎的支持,您可能必须将 ScriptEngine 库添加到您的路径中。可以在这里找到一篇解释如何使用 Android 和 Rhino 的好帖子。