How to evaluate a math expression given in string

2018-12-30 22:49发布

I'm trying to write a Java routine to evaluate simple math expressions from String values like:

  1. "5+3"
  2. "10-40"
  3. "10*3"

I want to avoid a lot of if-then-else statements. How can I do this?

标签: java string math
24条回答
千与千寻千般痛.
2楼-- · 2018-12-30 22:57

It is possible to convert any expression string in infix notation to a postfix notation using Djikstra's shunting-yard algorithm. The result of the algorithm can then serve as input to the postfix algorithm with returns the result of the expression.

I wrote an article about it here, with an implementation in java

查看更多
只靠听说
3楼-- · 2018-12-30 22:58
import java.util.*;
StringTokenizer st;
int ans;

public class check { 
   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; }
   //.........
}
查看更多
一个人的天荒地老
4楼-- · 2018-12-30 22:59

With JDK1.6, you can use the built-in Javascript engine.

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));
    } 
}
查看更多
回忆,回不去的记忆
5楼-- · 2018-12-30 23:00

Try the following sample code using JDK1.6's Javascript engine with code injection handling.

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;
    }
 }
}
查看更多
有味是清欢
6楼-- · 2018-12-30 23:07

Another way is to use Spring Expression Language or SpEL which does a whole lot more along with evaluating mathematical expressions therefore maybe slightly overkill. You do not have to be using Spring framework to use this expression library as it is stand-alone. Copying examples from SpEL's documentation:

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

Read more concise SpEL examples here and the complete docs here

查看更多
闭嘴吧你
7楼-- · 2018-12-30 23:07

if we are going to implement it then we can can use the below algorithm :--

  1. 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.
    
  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.

查看更多
登录 后发表回答