如何计算一个数学表达式给出的字符串形式?

我试图写一个Java例程来计算数学表达式从String值,如:

  1. "5+3"
  2. "10-40"
  3. "(1+10)*3"
我想避免很多if-then-else语句。 我该怎么做呢?< / p >
582489 次浏览

我想无论你用什么方法做这个都会涉及到很多条件命题。但是对于单个操作,比如在你的例子中,你可以将它限制为4个if语句

String math = "1+4";


if (math.split("+").length == 2) {
//do calculation
} else if (math.split("-").length == 2) {
//do calculation
} ...

当你想要处理像“4+5*6”这样的多个操作时,它会变得更加复杂。

如果你试图构建一个计算器,那么我建议分别传递计算的每个部分(每个数字或运算符),而不是作为一个单一的字符串。

正确的解决方法是使用词法分析程序解析器。您可以自己编写这些页面的简单版本,或者这些页面还包含指向Java词法分析器和解析器的链接。

创建递归下降解析器是非常好的学习练习。

似乎应该做这项工作

对于JDK1.6,您可以使用内置的Javascript引擎。

import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;


public class Test {
public static void main(String[] args) throws ScriptException {
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}
import java.util.*;


public class check {
int ans;
String str="7 + 5";
StringTokenizer st=new StringTokenizer(str);


int v1=Integer.parseInt(st.nextToken());
String op=st.nextToken();
int v2=Integer.parseInt(st.nextToken());


if(op.equals("+")) { ans= v1 + v2; }
if(op.equals("-")) { ans= v1 - v2; }
//.........
}

这篇文章讨论了各种方法。以下是文中提到的两种关键方法:

JEXL from Apache

允许脚本包含对java对象的引用。

// Create or retrieve a JexlEngine
JexlEngine jexl = new JexlEngine();
// Create an expression object
String jexlExp = "foo.innerFoo.bar()";
Expression e = jexl.createExpression( jexlExp );
 

// Create a context and add data
JexlContext jctx = new MapContext();
jctx.set("foo", new Foo() );
 

// Now evaluate the expression, getting the result
Object o = e.evaluate(jctx);

使用JDK中嵌入的javascript引擎:

private static void jsEvalWithVariable()
{
List<String> namesList = new ArrayList<String>();
namesList.add("Jill");
namesList.add("Bob");
namesList.add("Laureen");
namesList.add("Ed");
 

ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine jsEngine = mgr.getEngineByName("JavaScript");
 

jsEngine.put("namesListKey", namesList);
System.out.println("Executing in script environment...");
try
{
jsEngine.eval("var x;" +
"var names = namesListKey.toArray();" +
"for(x in names) {" +
"  println(names[x]);" +
"}" +
"namesListKey.add(\"Dana\");");
}
catch (ScriptException ex)
{
ex.printStackTrace();
}
}

你也可以尝试BeanShell解释器:

Interpreter interpreter = new Interpreter();
interpreter.eval("result = (7+21*6)/(32-27)");
System.out.println(interpreter.get("result"));

这样怎么样:

String st = "10+3";
int result;
for(int i=0;i<st.length();i++)
{
if(st.charAt(i)=='+')
{
result=Integer.parseInt(st.substring(0, i))+Integer.parseInt(st.substring(i+1, st.length()));
System.out.print(result);
}
}

并相应地对其他数学运算符做类似的事情。

在这里是GitHub上另一个名为EvalEx的开源库。

与JavaScript引擎不同,这个库只专注于计算数学表达式。此外,该库是可扩展的,支持使用布尔运算符和圆括号。

另一种方法是使用Spring表达式语言或SpEL,它在计算数学表达式时做了更多的工作,因此可能会略微过量。您不必使用Spring框架来使用这个表达式库,因为它是独立的。从SpEL文档中复制示例:

ExpressionParser parser = new SpelExpressionParser();
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2
double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); //24.0

我已经编写了算术表达式的eval方法来回答这个问题。它做加法、减法、乘法、除法、求幂(使用^符号),以及一些基本函数,如sqrt。它支持使用(),它使操作符优先级结合性规则正确。

public static double eval(final String str) {
return new Object() {
int pos = -1, ch;
        

void nextChar() {
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
}
        

boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}
        

double parse() {
nextChar();
double x = parseExpression();
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
return x;
}
        

// Grammar:
// expression = term | expression `+` term | expression `-` term
// term = factor | term `*` factor | term `/` factor
// factor = `+` factor | `-` factor | `(` expression `)` | number
//        | functionName `(` expression `)` | functionName factor
//        | factor `^` factor
        

double parseExpression() {
double x = parseTerm();
for (;;) {
if      (eat('+')) x += parseTerm(); // addition
else if (eat('-')) x -= parseTerm(); // subtraction
else return x;
}
}
        

double parseTerm() {
double x = parseFactor();
for (;;) {
if      (eat('*')) x *= parseFactor(); // multiplication
else if (eat('/')) x /= parseFactor(); // division
else return x;
}
}
        

double parseFactor() {
if (eat('+')) return +parseFactor(); // unary plus
if (eat('-')) return -parseFactor(); // unary minus
            

double x;
int startPos = this.pos;
if (eat('(')) { // parentheses
x = parseExpression();
if (!eat(')')) throw new RuntimeException("Missing ')'");
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(str.substring(startPos, this.pos));
} else if (ch >= 'a' && ch <= 'z') { // functions
while (ch >= 'a' && ch <= 'z') nextChar();
String func = str.substring(startPos, this.pos);
if (eat('(')) {
x = parseExpression();
if (!eat(')')) throw new RuntimeException("Missing ')' after argument to " + func);
} else {
x = parseFactor();
}
if (func.equals("sqrt")) x = Math.sqrt(x);
else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
else throw new RuntimeException("Unknown function: " + func);
} else {
throw new RuntimeException("Unexpected: " + (char)ch);
}
            

if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation
            

return x;
}
}.parse();
}

例子:

System.out.println(eval("((4 - 2^3 + 1) * -sqrt(3*3+4*4)) / 2"));

输出:7.5 (正确)


解析器是递归下降解析器,因此在语法中对每一层操作符优先级使用单独的解析方法。我故意保持它,但这里有一些想法,你可能想要扩展它:

  • < p > 变量:

    通过在传递给eval方法的变量表中查找名称,例如Map<String,Double> variables. xml方法,解析器中读取函数名的部分也可以轻松地更改为处理自定义变量。

  • < p > 单独编写和评估:

    如果增加了对变量的支持,您想用更改的变量对同一个表达式求值数百万次,而不是每次都解析它,该怎么办?这是有可能的。首先定义一个用于预编译表达式求值的接口:

      @FunctionalInterface
    interface Expression {
    double eval();
    }
    

    现在我们来重做一下原来的“eval"函数变成一个“解析”;函数,更改所有返回doubles的方法,因此它们返回该接口的一个实例。Java 8的lambda语法很好地解决了这个问题。其中一个更改方法的示例:

      Expression parseExpression() {
    Expression x = parseTerm();
    for (;;) {
    if (eat('+')) { // addition
    Expression a = x, b = parseTerm();
    x = (() -> a.eval() + b.eval());
    } else if (eat('-')) { // subtraction
    Expression a = x, b = parseTerm();
    x = (() -> a.eval() - b.eval());
    } else {
    return x;
    }
    }
    }
    

    这将构建一个由Expression对象组成的递归树,表示编译后的表达式(抽象语法树)。然后你可以编译它一次,用不同的值重复计算它:

      public static void main(String[] args) {
    Map<String,Double> variables = new HashMap<>();
    Expression exp = parse("x^2 - x + 2", variables);
    for (double x = -20; x <= +20; x++) {
    variables.put("x", x);
    System.out.println(x + " => " + exp.eval());
    }
    }
    
  • < p > 不同的数据类型:

    代替double,你可以改变求值器来使用更强大的东西,比如BigDecimal,或者实现复数或有理数(分数)的类。你甚至可以使用Object,允许在表达式中混合一些数据类型,就像真正的编程语言一样。:)


这个答案中的所有代码都发布了到公共域。玩得开心!

这是另一个有趣的选择 https://github.com/Shy-Ta/expression-evaluator-demo < / p >

它的用法非常简单,可以完成工作,例如:

  ExpressionsEvaluator evalExpr = ExpressionsFactory.create("2+3*4-6/2");
assertEquals(BigDecimal.valueOf(11), evalExpr.eval());

可以使用吉克斯特拉的调车场算法将中缀表示法中的任何表达式字符串转换为后缀表示法。然后,算法的结果可以作为后缀算法的输入,返回表达式的结果。

我写了一篇关于它的文章

如果我们要实现它,那么我们可以使用下面的算法

  1. 当仍有令牌要读入时,

    1.1获取下一个令牌。 1.2如果令牌为:

    1.2.1一个数字:将其推入值堆栈。

    1.2.2一个变量:获取其值,并将其推入值堆栈。

    1.2.3左括号:将其推入运算符堆栈。

    1.2.4右括号:

     1 While the thing on top of the operator stack is not a
    left parenthesis,
    1 Pop the operator from the operator stack.
    2 Pop the value stack twice, getting two operands.
    3 Apply the operator to the operands, in the correct order.
    4 Push the result onto the value stack.
    2 Pop the left parenthesis from the operator stack, and discard it.
    

    1.2.5一个操作符(称为thisOp):

     1 While the operator stack is not empty, and the top thing on the
    operator stack has the same or greater precedence as thisOp,
    1 Pop the operator from the operator stack.
    2 Pop the value stack twice, getting two operands.
    3 Apply the operator to the operands, in the correct order.
    4 Push the result onto the value stack.
    2 Push thisOp onto the operator stack.
    
  2. While the operator stack is not empty, 1 Pop the operator from the operator stack. 2 Pop the value stack twice, getting two operands. 3 Apply the operator to the operands, in the correct order. 4 Push the result onto the value stack.

  3. At this point the operator stack should be empty, and the value stack should have only one value in it, which is the final result.

现在回答已经太晚了,但我也遇到过同样的情况,在java中计算表达式,这可能会帮助到一些人

MVEL执行表达式的运行时求值,我们可以在String中编写java代码来让它在此中求值。

    String expressionStr = "x+y";
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("x", 10);
vars.put("y", 20);
ExecutableStatement statement = (ExecutableStatement) MVEL.compileExpression(expressionStr);
Object result = MVEL.executeExpression(statement, vars);

你可以看看Symja框架:

ExprEvaluator util = new ExprEvaluator();
IExpr result = util.evaluate("10-40");
System.out.println(result.toString()); // -> "-30"

请注意,可以计算更复杂的表达式:

// D(...) gives the derivative of the function Sin(x)*Cos(x)
IAST function = D(Times(Sin(x), Cos(x)), x);
IExpr result = util.evaluate(function);
// print: Cos(x)^2-Sin(x)^2

在我的大学项目中,我正在寻找一个既支持基本公式又支持更复杂方程(特别是迭代运算符)的解析器/求值器。我发现了一个非常好的JAVA和。net开源库,叫做mXparser。我将给出几个例子,让大家对语法有一些感觉,如需进一步指导,请访问项目网站(特别是教程部分)。

https://mathparser.org/

https://mathparser.org/mxparser-tutorial/

https://mathparser.org/api/

举几个例子

1 -简单的叉形

Expression e = new Expression("( 2 + 3/4 + sin(pi) )/2");
double v = e.calculate()

2 -用户定义的参数和常量

Argument x = new Argument("x = 10");
Constant a = new Constant("a = pi^2");
Expression e = new Expression("cos(a*x)", x, a);
double v = e.calculate()

3 -用户定义的函数

Function f = new Function("f(x, y, z) = sin(x) + cos(y*z)");
Expression e = new Expression("f(3,2,5)", f);
double v = e.calculate()

4 -迭代

Expression e = new Expression("sum( i, 1, 100, sin(i) )");
double v = e.calculate()

最近发现的-如果你想尝试语法(并查看高级用例),你可以下载由mXparser支持的标量 计算器 应用程序

还有另一个选项:https://github.com/stefanhaustein/expressionparser

我已经实现了一个简单而灵活的选项,以允许两者:

上面链接的TreeBuilder是CAS演示包的一部分,它进行符号推导。还有一个基本的翻译的例子,我已经开始使用它来构建一个打字稿翻译

如果Java应用程序已经访问了数据库,则无需使用任何其他jar,就可以轻松地计算表达式。

一些数据库要求你使用一个虚拟表(例如,Oracle的“dual”表),而另一些数据库则允许你在不从任何表中“选择”的情况下计算表达式。

例如,在Sql Server或Sqlite中

select (((12.10 +12.0))/ 233.0) amount

在Oracle中

select (((12.10 +12.0))/ 233.0) amount from dual;

使用DB的优点是可以同时计算多个表达式。此外,大多数DB将允许您使用高度复杂的表达式,也将有许多额外的函数,可以在必要时调用。

但是,如果需要分别计算许多单个表达式,性能可能会受到影响,特别是当DB位于网络服务器上时。

下面通过使用Sqlite内存数据库在一定程度上解决了性能问题。

下面是一个完整的Java工作示例

Class. forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite::memory:");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount");
rs.next();
System.out.println(rs.getBigDecimal(1));
stat.close();
conn.close();

当然,您可以扩展上面的代码以同时处理多个计算。

ResultSet rs = stat.executeQuery( "select (1+10)/20.0 amount, (1+100)/20.0 amount2");
package ExpressionCalculator.expressioncalculator;


import java.text.DecimalFormat;
import java.util.Scanner;


public class ExpressionCalculator {


private static String addSpaces(String exp){


//Add space padding to operands.
//https://regex101.com/r/sJ9gM7/73
exp = exp.replaceAll("(?<=[0-9()])[\\/]", " / ");
exp = exp.replaceAll("(?<=[0-9()])[\\^]", " ^ ");
exp = exp.replaceAll("(?<=[0-9()])[\\*]", " * ");
exp = exp.replaceAll("(?<=[0-9()])[+]", " + ");
exp = exp.replaceAll("(?<=[0-9()])[-]", " - ");


//Keep replacing double spaces with single spaces until your string is properly formatted
/*while(exp.indexOf("  ") != -1){
exp = exp.replace("  ", " ");
}*/
exp = exp.replaceAll(" {2,}", " ");


return exp;
}


public static Double evaluate(String expr){


DecimalFormat df = new DecimalFormat("#.####");


//Format the expression properly before performing operations
String expression = addSpaces(expr);


try {
//We will evaluate using rule BDMAS, i.e. brackets, division, power, multiplication, addition and
//subtraction will be processed in following order
int indexClose = expression.indexOf(")");
int indexOpen = -1;
if (indexClose != -1) {
String substring = expression.substring(0, indexClose);
indexOpen = substring.lastIndexOf("(");
substring = substring.substring(indexOpen + 1).trim();
if(indexOpen != -1 && indexClose != -1) {
Double result = evaluate(substring);
expression = expression.substring(0, indexOpen).trim() + " " + result + " " + expression.substring(indexClose + 1).trim();
return evaluate(expression.trim());
}
}


String operation = "";
if(expression.indexOf(" / ") != -1){
operation = "/";
}else if(expression.indexOf(" ^ ") != -1){
operation = "^";
} else if(expression.indexOf(" * ") != -1){
operation = "*";
} else if(expression.indexOf(" + ") != -1){
operation = "+";
} else if(expression.indexOf(" - ") != -1){ //Avoid negative numbers
operation = "-";
} else{
return Double.parseDouble(expression);
}


int index = expression.indexOf(operation);
if(index != -1){
indexOpen = expression.lastIndexOf(" ", index - 2);
indexOpen = (indexOpen == -1)?0:indexOpen;
indexClose = expression.indexOf(" ", index + 2);
indexClose = (indexClose == -1)?expression.length():indexClose;
if(indexOpen != -1 && indexClose != -1) {
Double lhs = Double.parseDouble(expression.substring(indexOpen, index));
Double rhs = Double.parseDouble(expression.substring(index + 2, indexClose));
Double result = null;
switch (operation){
case "/":
//Prevent divide by 0 exception.
if(rhs == 0){
return null;
}
result = lhs / rhs;
break;
case "^":
result = Math.pow(lhs, rhs);
break;
case "*":
result = lhs * rhs;
break;
case "-":
result = lhs - rhs;
break;
case "+":
result = lhs + rhs;
break;
default:
break;
}
if(indexClose == expression.length()){
expression = expression.substring(0, indexOpen) + " " + result + " " + expression.substring(indexClose);
}else{
expression = expression.substring(0, indexOpen) + " " + result + " " + expression.substring(indexClose + 1);
}
return Double.valueOf(df.format(evaluate(expression.trim())));
}
}
}catch(Exception exp){
exp.printStackTrace();
}
return 0.0;
}


public static void main(String args[]){


Scanner scanner = new Scanner(System.in);
System.out.print("Enter an Mathematical Expression to Evaluate: ");
String input = scanner.nextLine();
System.out.println(evaluate(input));
}

使用带有代码注入处理的JDK1.6 Javascript引擎尝试下面的示例代码。

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;


public class EvalUtil {
private static ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
public static void main(String[] args) {
try {
System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || 5 >3 "));
System.out.println((new EvalUtil()).eval("(((5+5)/2) > 5) || true"));
} catch (Exception e) {
e.printStackTrace();
}
}
public Object eval(String input) throws Exception{
try {
if(input.matches(".*[a-zA-Z;~`#$_{}\\[\\]:\\\\;\"',\\.\\?]+.*")) {
throw new Exception("Invalid expression : " + input );
}
return engine.eval(input);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}

这实际上是对@Boann给出的答案的补充。它有一个轻微的错误,导致“-2 ^ 2”给出一个错误的结果-4.0。这里的问题是求幂的点。只需将取幂运算移到parseTerm()的块中,就可以了。看看下面,它是@Boann的回答略有修改。修改意见见评论。

public static double eval(final String str) {
return new Object() {
int pos = -1, ch;


void nextChar() {
ch = (++pos < str.length()) ? str.charAt(pos) : -1;
}


boolean eat(int charToEat) {
while (ch == ' ') nextChar();
if (ch == charToEat) {
nextChar();
return true;
}
return false;
}


double parse() {
nextChar();
double x = parseExpression();
if (pos < str.length()) throw new RuntimeException("Unexpected: " + (char)ch);
return x;
}


// Grammar:
// expression = term | expression `+` term | expression `-` term
// term = factor | term `*` factor | term `/` factor
// factor = `+` factor | `-` factor | `(` expression `)`
//        | number | functionName factor | factor `^` factor


double parseExpression() {
double x = parseTerm();
for (;;) {
if      (eat('+')) x += parseTerm(); // addition
else if (eat('-')) x -= parseTerm(); // subtraction
else return x;
}
}


double parseTerm() {
double x = parseFactor();
for (;;) {
if      (eat('*')) x *= parseFactor(); // multiplication
else if (eat('/')) x /= parseFactor(); // division
else if (eat('^')) x = Math.pow(x, parseFactor()); //exponentiation -> Moved in to here. So the problem is fixed
else return x;
}
}


double parseFactor() {
if (eat('+')) return parseFactor(); // unary plus
if (eat('-')) return -parseFactor(); // unary minus


double x;
int startPos = this.pos;
if (eat('(')) { // parentheses
x = parseExpression();
eat(')');
} else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
x = Double.parseDouble(str.substring(startPos, this.pos));
} else if (ch >= 'a' && ch <= 'z') { // functions
while (ch >= 'a' && ch <= 'z') nextChar();
String func = str.substring(startPos, this.pos);
x = parseFactor();
if (func.equals("sqrt")) x = Math.sqrt(x);
else if (func.equals("sin")) x = Math.sin(Math.toRadians(x));
else if (func.equals("cos")) x = Math.cos(Math.toRadians(x));
else if (func.equals("tan")) x = Math.tan(Math.toRadians(x));
else throw new RuntimeException("Unknown function: " + func);
} else {
throw new RuntimeException("Unexpected: " + (char)ch);
}


//if (eat('^')) x = Math.pow(x, parseFactor()); // exponentiation -> This is causing a bit of problem


return x;
}
}.parse();
}

一个可以计算数学表达式的Java类:

package test;


public class Calculator {


public static Double calculate(String expression){
if (expression == null || expression.length() == 0) {
return null;
}
return calc(expression.replace(" ", ""));
}
public static Double calc(String expression) {
String[] containerArr = new String[]{expression};
double leftVal = getNextOperand(containerArr);
expression = containerArr[0];
if (expression.length() == 0) {
return leftVal;
}
char operator = expression.charAt(0);
expression = expression.substring(1);


while (operator == '*' || operator == '/') {
containerArr[0] = expression;
double rightVal = getNextOperand(containerArr);
expression = containerArr[0];
if (operator == '*') {
leftVal = leftVal * rightVal;
} else {
leftVal = leftVal / rightVal;
}
if (expression.length() > 0) {
operator = expression.charAt(0);
expression = expression.substring(1);
} else {
return leftVal;
}
}
if (operator == '+') {
return leftVal + calc(expression);
} else {
return leftVal - calc(expression);
}


}
    

private static double getNextOperand(String[] exp){
double res;
if (exp[0].startsWith("(")) {
int open = 1;
int i = 1;
while (open != 0) {
if (exp[0].charAt(i) == '(') {
open++;
} else if (exp[0].charAt(i) == ')') {
open--;
}
i++;
}
res = calc(exp[0].substring(1, i - 1));
exp[0] = exp[0].substring(i);
} else {
int i = 1;
if (exp[0].charAt(0) == '-') {
i++;
}
while (exp[0].length() > i && isNumber((int) exp[0].charAt(i))) {
i++;
}
res = Double.parseDouble(exp[0].substring(0, i));
exp[0] = exp[0].substring(i);
}
return res;
}




private static boolean isNumber(int c) {
int zero = (int) '0';
int nine = (int) '9';
return (c >= zero && c <= nine) || c =='.';
}


public static void main(String[] args) {
System.out.println(calculate("(((( -6 )))) * 9 * -1"));
System.out.println(calc("(-5.2+-5*-5*((5/4+2)))"));


}


}
像RHINO或NASHORN这样的外部库可以用来运行javascript。javascript可以计算简单的公式,而不需要对字符串进行分割。如果代码写得好,也不会对性能造成影响。 下面是RHINO -

的示例
public class RhinoApp {
private String simpleAdd = "(12+13+2-2)*2+(12+13+2-2)*2";


public void runJavaScript() {
Context jsCx = Context.enter();
Context.getCurrentContext().setOptimizationLevel(-1);
ScriptableObject scope = jsCx.initStandardObjects();
Object result = jsCx.evaluateString(scope, simpleAdd , "formula", 0, null);
Context.exit();
System.out.println(result);
}
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;


public class test2 {
public static void main(String[] args) throws ScriptException {
String s = "10+2";
ScriptEngineManager mn = new ScriptEngineManager();
ScriptEngine en = mn.getEngineByName("js");
Object result = en.eval(s);
System.out.println(result);
}
}

我已经使用迭代解析和分流码算法,我真的很喜欢开发表达式求值器,你可以在这里找到所有的代码

https://github.com/nagaraj200788/JavaExpressionEvaluator

有73个测试用例,甚至工作于大整数,大小数

支持所有关系表达式、算术表达式和两者的组合。 甚至支持三元运算符

增加了增强,以支持有符号的数字,如-100+89,这是有趣的,详细信息请检查TokenReader.isUnaryOperator()方法,我已经更新了上面链接中的代码