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

"5 + 3" "10-4 * 5" "(1 + 10) * 3"

我想避免很多如果-then-else语句。 我该怎么做呢?


当前回答

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

String math = "1+4";

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

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

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

其他回答

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

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

即时处理(Calculator.java, SetDemo.java) 构建和处理解析树(TreeBuilder.java)

上面链接的TreeBuilder是进行符号推导的CAS演示包的一部分。还有一个BASIC解释器的例子,我已经开始使用它来构建一个TypeScript解释器。

我想无论你用什么方法做这个都会涉及到很多条件命题。但是对于单个操作,比如在你的例子中,你可以将它限制为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中计算表达式,这可能会帮助到一些人

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);

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

While there are still tokens to be read in, 1.1 Get the next token. 1.2 If the token is: 1.2.1 A number: push it onto the value stack. 1.2.2 A variable: get its value, and push onto the value stack. 1.2.3 A left parenthesis: push it onto the operator stack. 1.2.4 A right parenthesis: 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 An operator (call it 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. 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. 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.

可以使用Djikstra的分流码算法将中缀表示法中的任何表达式字符串转换为后缀表示法。然后,算法的结果可以作为后缀算法的输入,并返回表达式的结果。

我在这里写了一篇关于它的文章,用java实现