首页 文章

评估以字符串形式给出的数学表达式[关闭]

提问于
浏览
269

我正在尝试编写一个Java例程来评估 String 值中的简单数学表达式,如:

  • "5+3"

  • "10-40"

  • "10*3"

我想避免很多if-then-else语句 . 我怎样才能做到这一点?

24 回答

  • 3

    使用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));
        } 
    }
    
  • 1

    我已经为算术表达式编写了这个 eval 方法来回答这个问题 . 它执行加法,减法,乘法,除法,取幂(使用 ^ 符号)和一些基本函数,如 sqrt . 它支持使用 ( ... ) 进行分组,并且它使运算符precedenceassociativity规则正确 .

    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 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
    
                return x;
            }
        }.parse();
    }
    

    例:

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

    输出:7.5 (which is correct)


    解析器是recursive descent parser,因此内部对其语法中的每个级别的运算符优先级使用单独的解析方法 . 我保留了它 short 所以它很容易修改,但是这里有一些你想要扩展它的想法:

    • Variables:

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

    • Separate compilation and evaluation:

    如果在添加对变量的支持后,您希望使用已更改的变量对相同的表达式进行数百万次计算,而不是每次都进行解析,该怎么办?这是可能的 . 首先定义用于评估预编译表达式的接口:

    @FunctionalInterface
    interface Expression {
        double eval();
    }
    

    现在更改返回 double 的所有方法,因此它们返回该接口的实例 . 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 对象树,表示编译后的表达式(abstract syntax tree) . 然后你可以编译一次并用不同的值重复评估它:

    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());
        }
    }
    
    • Different datatypes:

    而不是 double ,您可以更改评估程序以使用更强大的功能,如 BigDecimal ,或实现复数或有理数(分数)的类 . 您甚至可以使用 Object ,在表达式中允许混合使用某种数据类型,就像真正的编程语言一样 . :)


    此答案中的所有代码都发布到公共领域 . 玩得开心!

  • 2

    解决这个问题的正确方法是lexerparser . 您可以自己编写这些的简单版本,或者这些页面也有Java词法分析器和解析器的链接 .

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

  • 1

    HERE是GitHub上另一个名为EvalEx的开源库 .

    与JavaScript引擎不同,此库专注于仅评估数学表达式 . 此外,该库是可扩展的,并支持使用布尔运算符和括号 .

  • 1

    您也可以尝试BeanShell解释器:

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

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

    有些数据库要求您使用虚拟表(例如,Oracle的“双”表),而其他数据库则允许您在不从任何表“选择”的情况下评估表达式 .

    例如,在Sql Server或Sqlite中

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

    在Oracle中

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

    使用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");
    
  • 2

    对于我的大学项目,我一直在寻找一个解析器/评估器,支持基本公式和更复杂的方程(特别是迭代运算符) . 我找到了非常好的JAVA和.NET开源库,名为mXparser . 我将举几个例子来对语法有所了解,如需进一步说明,请访问项目网站(特别是教程部分) .

    http://mathparser.org/

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

    http://mathparser.org/api/

    几个例子

    1 - 简单的furmula

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

    最好的祝福

  • 13

    This article指向3种不同的方法,一种是JEXL from Apache,并允许包含对java对象的引用的脚本 .

  • 17

    另一种方法是使用Spring Expression Language或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
    

    阅读更简洁的SpEL示例here和完整的文档here

  • 5

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

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

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

    我认为无论你做什么,它都会涉及很多条件语句 . 但对于像您的示例中的单个操作,如果语句类似,则可以将其限制为4

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

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

    如果你正在尝试构建一个计算器,那么我将分别通过计算的每个部分(每个数字或运算符)而不是单个字符串 .

  • 7

    似乎JEP应该做的工作

  • 0

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

    • 虽然仍有令牌被读入,

    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.
    
    • 当操作员堆栈不为空时,1从操作员堆栈中弹出操作员 . 2弹出值栈两次,得到两个操作数 . 3以正确的顺序将操作符应用于操作数 . 4将结果推送到值堆栈 .

    • 此时操作符堆栈应为空,并且值堆栈中只应包含一个值,这是最终结果 .

  • 1

    您可以查看Symja framework

    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
    
  • 28

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

    我实现了这个有一个简单但灵活的选项,允许两者:

    上面链接的TreeBuilder是符号派生的CAS demo package的一部分 . 还有一个BASIC interpreter示例,我已经开始使用它构建TypeScript interpreter .

  • 5

    这实际上补充了@Boann给出的答案 . 它有一个小错误导致"-2 ^ 2"给出-4.0的错误结果 . 这个问题就是在他的评估中取幂的点 . 只需将取幂移动到parseTerm()块,你就会好起来的 . 看看下面的内容,这是@Boann's answer略有修改 . 修改在评论中 .

    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();
    }
    
  • 1

    使用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;
        }
     }
    }
    
  • 5
    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));
    }
    

    }

  • 1

    这样的事情怎么样:

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

    并相应地为每个其他数学运算符做类似的事情 .

  • 6

    可以使用Djikstra's shunting-yard algorithm将中缀表示法中的任何表达式字符串转换为后缀表示法 . 然后,算法的结果可以作为postfix algorithm的输入,并返回表达式的结果 .

    我写了一篇关于它的文章here, with an implementation in java

  • 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);
    
  • 13
    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; }
       //.........
    }
    
  • 330

    像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);
    }
    
  • 176

    一个可以评估数学表达式的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) {
    
            if (expression.startsWith("(") && expression.endsWith(")")) {
                return calc(expression.substring(1, expression.length() - 1));
            }
            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)))"));
    
        }
    
    }
    

相关问题