Существует ли простой способ взять Строку такой в качестве "5*4" и возвратиться 20?
Я не знаю, какие из них лучшие, но есть пакеты «оценщика математических выражений».
ознакомьтесь с Java Math Expression Evaluator ( один файл исходный код включен)
Пример использования с сайта:
java -cp meval.jar com.primalworld.math.MathEvaluator -cos (0) * (1 + 2)
java -cp meval.jar com.primalworld.math.MathEvaluator .05 * 200 + 3.01
Вы можете попробовать разобрать его самостоятельно, используя Integer.parseInt() и используя оператор switch() для поиска операторов.
Вы также можете попробовать использовать javax.script.ScriptEngine; для получения дополнительной информации смотрите http://forums.sun.com/thread.jspa?threadID=5144807.
Самым простым способом было бы использовать движок Rhino JavaScript , доступный со стандартным API JRE 6.
Изменить: согласно комментариям, если строки предоставлены пользователем, это может быть потенциальной дырой в безопасности. Обязательно отфильтруйте все, кроме цифр, фигурных скобок и математических операторов.
Возможно, вы ищете что-то вроде JbcParser - Math Parser for Java.
Я немного погуглил и нашел этот здесь . Это не совсем то, что вам нужно, но, может быть, это помогает несмотря ни на что.
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptDemo {
public static void main(String[] args) {
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
engine.put("a", 1);
engine.put("b", 2);
try {
String expression = "(a + b) > 2";
Object result = engine.eval(expression);
System.out.println(expression+" ? "+result);
} catch(ScriptException se) {
se.printStackTrace();
}
}
}
Более подробную информацию об оценке выражений можно найти в:
Похоже, вам стоит попробовать JEXL (язык выражений Java)
Это очень простое использование ; например, решение вашей проблемы:
public static void main(String[] args) {
long a = 5;
long b = 4;
String theExpression = "a * b";
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression(theExpression);
JexlContext context = new MapContext();
context.set("a", a);
context.set("b", b);
Long result = (Long) e.evaluate(context);
System.out.println("The answer : " + result);
}
В качестве альтернативы вы можете использовать следующее, если строка считывается напрямую:
public static void main(String[] args) {
JexlEngine jexl = new JexlEngine();
Expression e = jexl.createExpression("5 * 4");
Integer result = (Integer) e.evaluate(null);
System.out.println("The answer : " + result);
}
Раньше я использовал JEval и нашел его довольно простым и интуитивно понятным. Вот фрагмент кода:
import net.sourceforge.jeval.EvaluationException;
import net.sourceforge.jeval.Evaluator;
public class Main {
public static void main(String[] args) {
try {
System.out.println(new Evaluator().evaluate("5+4*3"));
}
catch (EvaluationException e) {
e.printStackTrace();
}
}
}
Лучше всего для этого использовать библиотеку. Янино имеет возможность оценивать произвольные выражения Java, подобные указанным вами, и многое другое.
Посмотрите пример ExpressionEvaluator .
Вы также можете использовать BeanShell .
На самом деле это больше интерпретатор исходного кода Java, но недавно я использовал его для оценки некоторых выражений, содержащих переменные (только метод eval
использует BeanShell, rest предназначен для подготовки вывода):
import bsh.EvalError;
import bsh.Interpreter;
public class EVAL {
private static final String FORMAT = "%-5s | %-5s | %-5s | %s%n";
public static void main(String[] args) {
tabela("((a && b)||c)");
tabela("a ? (b || c) : (b && c)");
tabela("(a?1:0) + (b?1:0) + (c?1:0) >= 2");
}
private static void tabela(String expressao) {
System.out.printf(FORMAT, " a ", " b ", " c ", expressao);
System.out.printf(FORMAT, "-----", "-----", "-----", expressao.replaceAll(".", "-"));
try {
for (int i = 0; i < 8; i++) {
boolean a = (i & (1<<2)) != 0;
boolean b = (i & (1<<1)) != 0;
boolean c = (i & (1<<0)) != 0;
boolean r = eval(expressao, a, b, c);
System.out.printf(FORMAT, a, b, c, r);
}
} catch (EvalError ex) {
ex.printStackTrace();
}
System.out.println();
System.out.println();
}
private static boolean eval(String expressao, boolean a, boolean b, boolean c) throws EvalError {
Interpreter inter = new Interpreter();
inter.set("a", a);
inter.set("b", b);
inter.set("c", c);
Object resultado = inter.eval(expressao);
return (Boolean) resultado;
}
}
результаты:
a | b | c | ((a && b)||c)
----- | ----- | ----- | -------------
false | false | false | false
false | false | true | true
false | true | false | false
false | true | true | true
true | false | false | false
true | false | true | true
true | true | false | true
true | true | true | true
a | b | c | a ? (b || c) : (b && c)
----- | ----- | ----- | -----------------------
false | false | false | false
false | false | true | false
false | true | false | false
false | true | true | true
true | false | false | false
true | false | true | true
true | true | false | true
true | true | true | true
a | b | c | (a?1:0) + (b?1:0) + (c?1:0) >= 2
----- | ----- | ----- | --------------------------------
false | false | false | false
false | false | true | false
false | true | false | false
false | true | true | true
true | false | false | false
true | false | true | true
true | true | false | true
true | true | true | true