精华内容
下载资源
问答
  • JavaJava数学表达式计算(Expression Evaluator)常见的表达式计算lib有:parsiiJEvalJEPLiteexprJaninoMathEval(1)parsiiJava代码String exp = "2 + (7-5) * 3.14159 * x + sin(0)";// compile Scope scope = Scope....

    Java

    Java数学表达式计算(Expression Evaluator)

    常见的表达式计算lib有:parsiiJEvalJEPLiteexprJaninoMathEval(1)parsii

    Java代码String exp = "2 + (7-5) * 3.14159 * x + sin(0)";

    // compile Scope scope = Scope.create(); Expression parsiiExpr = Parser.parse(exp); Variable var =

    scope.getVariable("x"); var.setValue(X_V ALUE); // evaluate double result = parsiiExpr.evaluate();

    System.out.println(result);//-> 2.0 (2)JEval

    Java代码String exp = "2 + (7-5) * 3.14159 * #{x} + sin(0)"; // compile Evaluator jevalEvaluator = new Evaluator(); jevalEvaluator.setVariables(Collections.singletonMap("x", Double.toString(X_V ALUE))); // evaluate double result = Double.parseDouble(jevalEvaluator.evaluate(exp)); System.out.println(result);//-> 2.0 (3)JEPLite

    Java代码String exp = "2 + (7-5) * 3.14159 * x + sin(0)";

    // compile JEP jep = new JEP(); jep.addVariable("x",

    X_V ALUE); jep.parseExpression(exp); DoubleStack jepStack = new DoubleStack(); // evaluate double result = jep.getValue(jepStack); System.out.println(result);//->

    2.0

    展开全文
  • 可以支持复杂的数学表达式(常量、变量、带括号)的计算 如123 + (a * 456)/c - (d + 789) 输入变量值,展示计算步骤和结果 目前支持+ - * / 幂 cos等操作 操作符可方便扩展
  • java数学表达式计算算法

    千次阅读 2009-11-16 23:53:00
    java数学表达式算法、云客服、在线客服系统、在线客服、一洽在线客服

    数学表达式计算算法,为了方便直接将数值类型格式化为了double,看到的朋友帮忙测测

    计算规则,先%,后* /再+ -先括号内在括号外先左后右,只是写了个算法的思路,有些细节没有处理,有时间补上。

     

    此算法采用操作符进栈比较优先级的策略决定是否计算栈顶操作符的表达式。记得大学时写编译器的时候我用的是循环检测栈内最内层的括号,找到后按照 % * / + -的优先级顺序进行脱括号计算,知道没有括号后在进行一轮的循环计算。此算法代码的实现上和逻辑上较为简单,本文的算法是根据数据结构中给的算法思路整理的java代码算法。

     

    /**author:a276202460*CreateDate:2009-11-17**/
    package com.rich.expression;
    import java.util.Stack;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class ExpressionOptr {
        private static final String optrflag = "(#+-#*/#%)";
        private static final Pattern errorpattern = Pattern.compile("([^0-9//+//-//*///(//)//. %]|" + "[^0-9]{1,}//.[^0-9]{1,}|" + "^//.|" + "//.$|" + "//([^0-9//( ]|" + "[^0-9//) ]//)|" + "[^//+//-//*///(% ]//(|" + "//)[^//+//-//*///) %])");
        private static Matcher m;
    
        public static void main(String[] s) {
            String expression = " 3.2 * ( 5.3+3.4-5.5 / 4 ) + 9 -4 %(5-2) ";
            System.out.println(getResult(expression));
            System.out.println(3.2 * (5.3 + 3.4 - 5.5 / 4) + 9 - 4 % (5 - 2));
        }
    
        public static double getResult(String expression) {
            String validatestr = validateExpression(expression);
            if (validatestr != null) {
                throw new RuntimeException("Error with unexpected char:" + validatestr);
            }
            expression = expression.trim();
            expression = expression.replaceAll("//+", " + ").replaceAll("//-", " - ").replaceAll("//*", " * ").replaceAll("/", " / ").replaceAll("%", " % ").replaceAll("//(", " ( ").replaceAll("//)", " ) ").replaceAll(" +", " ").replaceAll("^ ", "").replaceAll(" $", "");
            Stack valuestack = new Stack();
            Stack optrstack = new Stack();
            String[] expchars = expression.split(" +");
            int startindex = 0;
            String ep;
            String top;
            while (startindex < expchars.length) {
                ep = expchars[startindex];
                startindex++;
                if (optrflag.indexOf(ep) == -1) {
                    valuestack.push(ep);
                } else {
                    if (optrstack.isEmpty()) {
                        optrstack.push(ep);
                        continue;
                    }
                    top = optrstack.pop().toString();
                    int rs = comparepri(top, ep);
                    if (rs == 0) {
                        continue;
                    } else if (rs < 0) {
                        optrstack.push(top);
                        optrstack.push(ep);
                    } else {
                        startindex--;
                        double b = Double.parseDouble(valuestack.pop().toString());
                        double a = Double.parseDouble(valuestack.pop().toString());
                        valuestack.push("" + getresult(a, b, top));
                    }
                }
            }
            while (!optrstack.isEmpty()) {
                double b = Double.parseDouble(valuestack.pop().toString());
                double a = Double.parseDouble(valuestack.pop().toString());
                valuestack.push("" + getresult(a, b, optrstack.pop().toString()));
            }
            return Double.parseDouble(valuestack.pop().toString());
        }
    
        public static String validateExpression(String expression) {
            expression = expression.replaceAll(" +", " ");
            m = errorpattern.matcher(expression);
            if (m.find()) {
                return m.group(1);
            }
            m = errorpattern.matcher(expression.trim());
            if (m.find()) {
                return m.group(1);
            }
            return null;
        }
    
        private static int comparepri(String top, String insert) {
            int i = optrflag.indexOf(top);
            int j = optrflag.indexOf(insert);
            if (i < 0 || i == 1 || i == 4 || i == 7 || j < 0 || j == 1 || j == 4 || j == 7) {
                throw new RuntimeException("Error");
            }
            int distance = j - i;
            if (distance == -9) {
                throw new RuntimeException("Error");
            }
            if (distance == 9) {
                return 0;
            } else if (i == j && i != 0) {
                return 1;
            } else if (i == j && i == 0) {
                return -1;
            } else if (j == 9) {
                return 1;
            } else if (j == 0) {
                return -1;
            } else if (j - i <= 1) {
                return 1;
            } else {
                return -1;
            }
        }
    
        public static double getresult(double a, double b, String operator) {
            char operat = operator.toCharArray()[0];
            switch (operat) {
                case '%':
                    return getmod(a, b);
                case '+':
                    return getsum(a, b);
                case '-':
                    return getgap(a, b);
                case '*':
                    return getproduct(a, b);
                case '/':
                    return getquotient(a, b);
                default: {
                    throw new RuntimeException("Error");
                }
            }
        }
    
        public static double getsum(double a, double b) {
            return a + b;
        }
    
        public static double getgap(double a, double b) {
            return a - b;
        }
    
        public static double getproduct(double a, double b) {
            return a * b;
        }
    
        public static double getquotient(double a, double b) {
            if (b == 0) {
                throw new RuntimeException("Error with / 0");
            }
            return a / b;
        }
    
        public static double getmod(double a, double b) {
            if (b == 0) {
                throw new RuntimeException("Error with % 0");
            }
            return a % b;
        }
    }

     

     

     学生时代的算法现在用到了自己的产品中,发现各方面表现还不错,特回来备注留念下当时的烂代码。

    一洽在线客服软件

    展开全文
  • Exp4j是一个简单易用的开源Java数学表达式计算工具,由德国Java开源爱好者Frank发起并持续进行维护,旨在提供对数学表达式的计算功能。 实际使用一下: packageorg.demo.exp4j; importde.congrace.exp4j....

    Exp4j是一个简单易用的开源Java数学表达式计算工具,由德国Java开源爱好者Frank发起并持续进行维护,旨在提供对数学表达式的计算功能。

    实际使用一下:

     
     
    1. package org.demo.exp4j; 
    2.  
    3. import de.congrace.exp4j.Calculable; 
    4. import de.congrace.exp4j.ExpressionBuilder; 
    5. import de.congrace.exp4j.UnknownFunctionException; 
    6. import de.congrace.exp4j.UnparsableExpressionException; 
    7.  
    8. /** 
    9.  * Exp4j Demo 
    10.  * @author William Xu 
    11.  */ 
    12. public class Exp4jDemo { 
    13.  
    14.     // 包含变量的数学表达式 
    15.     private final String FUNCTION = "x/y + (x+y)*z"
    16.  
    17.     public Exp4jDemo() { 
    18.  
    19.     } 
    20.  
    21.     public void testFunction() { 
    22.  
    23.         // 构建表达式,并声明变量定义 
    24.         ExpressionBuilder builder = new ExpressionBuilder(FUNCTION) 
    25.                 .withVariableNames("x""y""z"); 
    26.          
    27.         // 以下两种方式也可以声明变量,并直接给变量进行赋值 
    28.         /*ExpressionBuilder.withVariable(String var,double value) 
    29.         ExpressionBuilder.withVariables(Map<String,Double> variables)*/ 
    30.          
    31.         try { 
    32.              
    33.             // 生成计算对象 
    34.             Calculable calc = builder.build(); 
    35.  
    36.             // 设置变量的值 
    37.             calc.setVariable("x"5); 
    38.             calc.setVariable("y"3); 
    39.             calc.setVariable("z"4); 
    40.  
    41.             // 计算结果 
    42.             System.out.println(calc.calculate()); 
    43.  
    44.         } catch (UnknownFunctionException e) { 
    45.             e.printStackTrace(); 
    46.         } catch (UnparsableExpressionException e) { 
    47.             e.printStackTrace(); 
    48.         } 
    49.     } 
    50.  
    51.  
    52.     public static void main(String[] args) { 
    53.  
    54.         Exp4jDemo exp4jDemo = new Exp4jDemo(); 
    55.          
    56.         exp4jDemo.testFunction(); 
    57.  
    58.  
    59.     } 

    Exp4j所支持的运算符包括:

    • 加法:“2 + 2
    • 减法:“2 - 2”
    • 乘法:“2 * 2
    • 除法:“2 / 2
    • 取模:“2 % 2”
    • 正负号:“+2 - (-2)”
    • 幂:“2 ^ 2”
    内建函数包括:
    • abs: absolute value
    • acos: arc cosine
    • asin: arc sine
    • atan: arc tangent
    • cbrt: cubic root
    • ceil: nearest upper integer
    • cos: cosine
    • cosh: hyperbolic cosine
    • exp: euler's number raised to the power (e^x)
    • floor: nearest lower integer
    • log: logarithmus naturalis (base e)
    • sin: sine
    • sinh: hyperbolic sine
    • sqrt: square root
    • tan: tangent
    • tanh: hyperbolic tangent



    本文转自william_xu 51CTO博客,原文链接:http://blog.51cto.com/williamx/1065823,如需转载请自行联系原作者

     

     

    展开全文
  • java写的数学表达式计算程序,报告内含代码,能直接运行。
  • 用几行代码,CalM使您的应用程序可以评估用户提供的数学表达式,例如“ e ^(sin .25pi)”和“(sqrt e)^(sqrt 2)”。 解析器的标准配置具有多种数学运算,包括基本算术,三角函数,组合函数,线性代数等。 ...
  • 数学计算的加减乘除人脑算很简单,但是放到计算中却需要进行一些转换,在正式写Java计算数学表达式前,我们需要先来介绍两个概念:前缀表达式、中缀表达式和后缀表达式;(这里的某缀指的是符号的位置) 中缀表达式...

    一、前言

    数学计算的加减乘除人脑算很简单,但是放到计算中却需要进行一些转换,在正式写Java计算数学表达式前,我们需要先来介绍两个概念:前缀表达式、中缀表达式和后缀表达式;(这里的某缀指的是符号的位置)
    中缀表达式:我们所接收的教育中所学的就为中缀表达式,形如(ab/c-d+e),也即表达式中的运算符号在数字的中间且有运算符的优先级。
    后缀表达式:后缀表达式即运算符号位于操作数的后面,形如(ab
    c/d-e+),需要从左往右计算,可以不用考虑优先级,是一种线性的计算,也是计算机易于计算的一种方式;
    前缀表达式:前缀表达式可由后缀表达式可知,运算符号位于操作数之前,形如(±/*abcde),也是一种计算机易于计算的一种方式。
    介绍完上面的数学表达式的三种方式以后,就解决了我们用Java计算数学表达式的第一步了,将中缀表达式(人类易于理解)转换为后缀表达式(计算机易于计算);

    二、中缀表达式转后缀表达式

    将中缀表达式转换为后缀表达式可以借助堆栈实现,具体转换方式;
    (1)从左到右进行遍历
    (2)如果是运算数,则直接输出
    (3)如果是左括号,则直接压入堆栈(括号是最高优先级)入栈后变成优先级最低的,确保其它运算符号能够正常入栈。
    如果遇到的是右括号,则说明这个括号中的式子已经结束了,弹出并输出栈顶元素直到遇到左括号为止,遇到左括号弹出但不输出;
    如果遇到运算符(加、减、乘、除运算符),将该运算符与栈顶运算符进行比较,
    如果优先级高于栈顶运算符则压入堆栈;如果优先级低于栈顶运算符则将栈顶运算符弹出并输出,并比较新的栈顶运算符直到优先级大于栈顶元素或者栈空的时候在将该运算符入栈。
    如果处理完毕后,栈不为空,则依次弹出并输出。
    代码如下:

    public static String infixToSuffix(String expression) {
            // 创建操作符堆栈
            Stack<Character> stack = new Stack<>();
            // 要输出的后缀表达式字符串
            StringBuild suffix = new StringBuild();
            for (int i = 0; i < expression.length(); i++) {
                // 中间变量
                char temp;
                // 获取该中缀表达式的每一个字符进行判断
                char ch = expression.charAt(i);
                switch (ch) {
                    // 过滤空格
                    case ' ':
                        break;
                    // 遇到左括号直接入栈
                    case '(':
                        stack.push('(');
                        break;
                    // 遇到+、- 运算符,将栈中的所有运算符全部弹出,遇到堆栈中的左括号为止
                    case '+':
                    case '-':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(') {
                                stack.push('(');
                                break;
                            }
                            suffix.append(temp);
                        }
                        // 没有进入循环说明当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
                        stack.push(ch);
                        break;
                    // 遇到*、/ 运算符,则将堆栈中的所有运算符全部弹出,遇到加号、减号以及左括号为止
                    case '*':
                    case '/':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '+' || temp == '-' || temp == '(') {
                                stack.push(temp);
                                break;
                            }
                            suffix.append(temp);
                        }
                        // 没有进入循环说明当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
                        stack.push(ch);
                        break;
                    // 遇到右括号,则弹出所有运算符直到遇到左括号为止,并抛弃左括号。
                    case ')':
                        while (!stack.isEmpty()) {
                            temp = stack.pop();
                            if (temp == '(') {
                                // 这里左括号不重新入栈了
                                break;
                            }
                            suffix.append(temp);
                        }
                        break;
                     // 默认情况下,将作为操作数直接输出到队列中
                    default:
                        suffix.append(ch);
                        break;
                }
            }
            // 如果堆栈不为空,则把剩余的运算符一次弹出,输出到队列中
            while (!stack.isEmpty()) {
                suffix.append(stack.pop());
            }
            // 返回后缀表达式
            return suffix.toString();
        }
    

    我们做一下测试,将中缀表达式a+b*c+(d-e)/f-g 转换为后缀表达式(这里先用字母代替数字),main方式如下:

    public static void main(String[] args) {
            System.out.println(Calculation.infixToSuffix("a+b*c+(d-e)/f-g"));
        }
    

    转换后的后缀表达式为:abc*+de-f/+g-
    打印每次for循环堆栈的大小以及输出能够更好的如和将中缀表达式转换为后缀表达式

    com.zlc.otherproject.calculationutil.Calculation
    第1次
    堆栈中的数据大小0
    输出为a
    第2次
    堆栈中的数据大小1
    输出为a
    第3次
    堆栈中的数据大小1
    输出为ab
    第4次
    堆栈中的数据大小2
    输出为ab
    第5次
    堆栈中的数据大小2
    输出为abc
    第6次
    堆栈中的数据大小1
    输出为abc*+7次
    堆栈中的数据大小2
    输出为abc*+8次
    堆栈中的数据大小2
    输出为abc*+d
    第9次
    堆栈中的数据大小3
    输出为abc*+d
    第10次
    堆栈中的数据大小3
    输出为abc*+de
    第11次
    堆栈中的数据大小1
    输出为abc*+de-12次
    堆栈中的数据大小2
    输出为abc*+de-13次
    堆栈中的数据大小2
    输出为abc*+de-f
    第14次
    堆栈中的数据大小1
    输出为abc*+de-f/+15次
    堆栈中的数据大小1
    输出为abc*+de-f/+g
    中缀表达式转换后缀表达式为:abc*+de-f/+g-
    
    Process finished with exit code 0
    
    

    三、计算后缀表达式

    计算后缀表达式还可以借助堆栈来实现,从左到右依次读取,如果为数字则直接入栈,遇到运算符则弹出栈顶元素与弹出栈顶元素后的新栈顶元素进行运算;需要注意的地方就是除法被除数不能为0这种了。(数值计算使用了BigDecimal)
    计算后缀表达式代码如下:

        /**
         * 定义公式计算符号
         */
        public static final String ADD = "+";
        public static final String SUBTRACTION = "-";
        public static final String MULTIPLICATION = "*";
        public static final String DIVISION = "/";
    
    public static BigDecimal suffixToArithmetic(String express) throws ArithmeticException {
            // 将后缀表达式分割成字符串数组,此处直接使用空白也可以对字符串进行分割!!
            // 定义一个操作符集合,用于判断是否为操作符(后缀表达式中已经没有了左右括号)
            List<String>  operatorList = Arrays.asList("+","-","*","/");
            String[] values = express.split("");
            Stack<BigDecimal> stack = new Stack<>();
            String value;
            for (String s : values) {
                // 这里最好是进行判断彻底消除空格,在该数组的第一位为一个隐形的空格,这里一定要注意在使用exp.split("")剔除空白""
                value = s;
                // 由于使用的是""截取导致在数组第一位上面的值为空白
                if (StringUtils.isBlank(value)) {
                    continue;
                }
                // 如果遇到了数字,放入操作数栈等待计算
                if(!operatorList.contains(value)){
                    stack.push(new BigDecimal((value)));
                } else {
                    // 如果是运算符,则弹出栈顶的两个数进行计算
                    // x为第一次弹出的栈顶元素,这里面的顺序不能错
                    BigDecimal x = stack.pop();
                    BigDecimal y = stack.pop();
                    // 将运算结果重新压栈
                    stack.push(calculate(x, y, value));
                }
            }
            // 弹出栈顶元素就是最终结果
            return stack.pop();
        }
    
        /**
         * 这里需要注意x为第一次弹出栈顶的数,所以下面的加减乘除使用y操作x
         * @param x 操作数
         * @param y 操作数
         * @param operator 操作符
         * @return  计算结果
         */
        private static BigDecimal calculate(BigDecimal x, BigDecimal y, String operator) {
            BigDecimal calculateResult;
            switch (operator.trim()){
                case Calculation.ADD:
                     calculateResult = y.add(x);
                     break;
                case Calculation.SUBTRACTION:
                     calculateResult = y.subtract(x);
                     break;
                case Calculation.MULTIPLICATION:
                     calculateResult = y.multiply(x);
                     break;
                case Calculation.DIVISION:
                     if (x.intValue() == 0){
                         throw new ArithmeticException("被除数为0,无法计算!");
                     }else {
                         // 结果保留4位小数
                         calculateResult = y.divide(x,4,RoundingMode.HALF_UP);
                     }
                     break;
                default:
                    throw new ArithmeticException("无法运算的运算符!");
            }
            return calculateResult;
        }
    

    我们做一下测试,计算中缀表达式1+2*3+(4-2)/2-4,计算结果为4,保丢4位小数位4.0000.

    public static void main(String[] args) {
            String infixExpression = "1+2*3+(4-2)/2-4";
            String postfixExpression = Calculation.infixToSuffix(infixExpression);
            System.out.println("中缀表达式:" + infixExpression +"转换为后缀表达式后为:" + postfixExpression);
            System.out.println("计算结果为:" + Calculation.suffixToArithmetic(postfixExpression));
        }
    

    计算结果如下:

    中缀表达式:1+2*3+(4-2)/2-4转换为后缀表达式后为:123*+42-2/+4-
    计算结果为:4.0000
    
    Process finished with exit code 0
    

    四、计算形式公式

    上面的例子我们计算的公式只能是公式中的数字已经确定好的,这样还不够灵活,下面使用26个小写的英文字母代替数字,使用字母作为形式计算数字,为相应的字母赋值,计算相应的数学公式计算结果,对上面的代码进行一些改造。

    package com.zlc.javaproject.calculationutils;
    
    import org.apache.commons.lang.StringUtils;
    
    import java.math.BigDecimal;
    import java.math.RoundingMode;
    import java.util.*;
    import java.util.regex.Pattern;
    
    import static java.util.regex.Pattern.compile;
    
    /**
     * @author Jacob
     * @version 1.0
     * @date 2020/9/14 20:43
     */
    public class Calculation {
        /**
         * 定义公式计算符号
         */
        private static final String ADD = "+";
        private static final String SUBTRACTION = "-";
        private static final String MULTIPLICATION = "*";
        private static final String DIVISION = "/";
    
        /**
         * @param expression 计算公式
         * @param param 参数
         * @return  根据计算公式返回结果
         */
        public static BigDecimal getCalculateResult(String expression, Map<String,String> param) throws ArithmeticException{
            return stringToArithmetic(expression, param);
        }
    
        /**
         * @param string 中缀表达式
         * @param map 公式形参实参map
         * @return 公式计算结果
         * @throws ArithmeticException 计算异常
         */
        private static BigDecimal stringToArithmetic(String string, Map<String, String> map) throws ArithmeticException{
            return suffixToArithmetic(infixToSuffix(string), map);
        }
    
        /**
         * @param expression 中缀表达式
         * @return  后缀表达式
         */
        public static String infixToSuffix(String expression) {
            // 创建操作符堆栈
            Stack<Character> stack = new Stack<>();
            StringBuilder suffix = new StringBuilder();
            for (int i = 0; i < expression.length(); i++) {
                // 中间变量
                char temp;
                // 获取该中缀表达式的每一个字符进行判断
                char ch = expression.charAt(i);
                switch (ch) {
                    // 过滤空格
                    case ' ':
                        break;
                    // 遇到左括号直接入栈
                    case '(':
                        stack.push('(');
                        break;
                    // 遇到+、- 运算符,将栈中的所有运算符全部弹出,遇到堆栈中的左括号为止
                    case '+':
                    case '-':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '(') {
                                stack.push('(');
                                break;
                            }
                            suffix.append(temp);
                        }
                        // 没有进入循环说明当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
                        stack.push(ch);
                        break;
                    // 遇到*、/ 运算符,则将堆栈中的所有运算符全部弹出,遇到加号、减号以及左括号为止
                    case '*':
                    case '/':
                        while (stack.size() != 0) {
                            temp = stack.pop();
                            if (temp == '+' || temp == '-' || temp == '(') {
                                stack.push(temp);
                                break;
                            }
                            suffix.append(temp);
                        }
                        // 没有进入循环说明当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
                        stack.push(ch);
                        break;
                    // 遇到右括号,则弹出所有运算符直到遇到左括号为止,并抛弃左括号。
                    case ')':
                        while (!stack.isEmpty()) {
                            temp = stack.pop();
                            if (temp == '(') {
                                // 这里左括号不重新入栈了
                                break;
                            }
                            suffix.append(temp);
                        }
                        break;
                    // 默认情况下,将作为操作数直接输出到队列中
                    default:
                        suffix.append(ch);
                        break;
                }
            }
            // 如果堆栈不为空,则把剩余的运算符一次弹出,输出到队列中
            while (!stack.isEmpty()) {
                suffix.append(stack.pop());
            }
            // 返回后缀表达式
            return suffix.toString();
        }
    
        /**
         * @param express 需要计算的后缀表达式
         * @return 计算结果
         * @throws ArithmeticException 计算异常
         */
        public static BigDecimal suffixToArithmetic(String express, Map<String, String> map) throws ArithmeticException {
            // 使用正则表达式匹配数字
            Pattern pattern = compile("[a-z]");
            // 将后缀表达式分割成字符串数组,此处直接使用空白也可以对字符串进行分割!!
            // 定义一个操作符集合,用于判断是否为操作符(后缀表达式中已经没有了左右括号)
            List<String> operatorList = Arrays.asList("+","-","*","/");
            String[] values = express.split("");
            Stack<BigDecimal> stack = new Stack<>();
            String value;
            for (String s : values) {
                // 这里最好是进行判断彻底消除空格,在该数组的第一位为一个隐形的空格,这里一定要注意在使用exp.split("")剔除空白""
                value = s;
                // 由于使用的是""截取导致在数组第一位上面的值为空白
                if (StringUtils.isBlank(value)) {
                    continue;
                }
                // 如果遇到了数字,放入操作数栈等待计算
                if(!operatorList.contains(value)){
                    stack.push(new BigDecimal(map.get(value)));
                } else {
                    // 如果是运算符,则弹出栈顶的两个数进行计算
                    // x为第一次弹出的栈顶元素,这里面的顺序不能错
                    BigDecimal x = stack.pop();
                    BigDecimal y = stack.pop();
                    // 将运算结果重新压栈
                    stack.push(calculate(x, y, value));
                }
            }
            // 弹出栈顶元素就是最终结果
            return stack.pop();
        }
    
        /**
         * 这里需要注意x为第一次弹出栈顶的数,所以下面的加减乘除使用y操作x
         * @param x 操作数
         * @param y 操作数
         * @param operator 操作符
         * @return  计算结果
         */
        private static BigDecimal calculate(BigDecimal x, BigDecimal y, String operator) {
            BigDecimal calculateResult;
            switch (operator.trim()){
                case Calculation.ADD:
                    calculateResult = y.add(x);
                    break;
                case Calculation.SUBTRACTION:
                    calculateResult = y.subtract(x);
                    break;
                case Calculation.MULTIPLICATION:
                    calculateResult = y.multiply(x);
                    break;
                case Calculation.DIVISION:
                    if (x.intValue() == 0){
                        throw new ArithmeticException("被除数为0,无法计算!");
                    }else {
                        // 结果保留4位小数
                        calculateResult = y.divide(x,4, RoundingMode.HALF_UP);
                    }
                    break;
                default:
                    throw new ArithmeticException("无法运算的运算符!");
            }
            return calculateResult;
        }
    
        public static void main(String[] args) {
            // 中缀表达式 1+2*3+(4-2)/2-4
            String infixExpression = "a+b*c+(d-b)/b-d";
            Map<String, String> params = new HashMap<>(16);
            params.put("a","1");
            params.put("b", "2");
            params.put("c","3");
            params.put("d","4");
            String postfixExpression = Calculation.infixToSuffix(infixExpression);
            System.out.println("中缀表达式:" + infixExpression +"转换为后缀表达式后为:" + postfixExpression);
            System.out.println("计算结果为:" + Calculation.getCalculateResult(infixExpression,params));
        }
    }
    
    

    运行结果如下:

    中缀表达式:a+b*c+(d-b)/b-d转换为后缀表达式后为:abc*+db-b/+d-
    计算结果为:4.0000
    

    经过上面的代码改造就可以使计算更加的灵活方便。

    五、有兴趣的小伙伴可以关注我的微信公众号,闲来看一看,感谢!

    在这里插入图片描述

    展开全文
  • NULL 博文链接:https://rensanning.iteye.com/blog/2011558
  • 这个表达式相对别的计算工具,优点主要体现在: A、不需要预先加载可能需要的所有属性值 B、 用户可以根据业务需要自定义操作符号和函数  C、可以同步输出判断错误信息,有利于提高业务系统在规则判断等使用场景...
  • Java数学表达式API JFormula发布3.2版本

    千次阅读 2005-06-16 22:56:00
    JFormula 3.2 - Math expressions APIFormula is a library for evaluating various mathematical expressions. User can evaluate instantly a string setting variables, adding its own functions or operators.M
  • java 计算数学表达式

    2010-12-04 22:16:00
    java 计算数学表达式
  • 主要介绍了Java计算数学表达式代码详解,具有一定借鉴价值,需要的朋友可以了解下。
  • java计算数学表达式

    2013-05-07 12:55:07
    java计算数学表达式,加减乘除,用正则表达式
  • 目标:通过设计一个简单的数学表达式计算器,要求设计者以面向对象程序的设计方式来实现计算器的具体功能。 程序规则: (1)表达式定义 本程序表达式设定为可由多个运算符和数字组成,可以含括号,为了降低题目...
  • ExpressionGenerator Java随机数学表达式生成器
  • I am working on this regex((([(]?[-]?[0-9]*[.]?[0-9]+)+([\/\+\-\*])+)+([0-9]*[.]?[0-9]+[)]?)+[\+\-\*\/]?([0-9]*)*)+I need this to accept any expression like: (2+2*7)-4+2/(5-3)+2and I want to avoid exp...
  • java代码实现中缀表达式转后缀表达式,并计算结果
  • 作为家庭作业和相互递归的介绍,我们应该编写一个使用相互递归的数学表达式求值器. getExpressionValue,getTermValue和getFactorValue这三个方法需要相互调用才能获得结果.我们应该支持加,减,乘,除和带括号的表达式....
  • java复杂数学表达式的计算

    千次阅读 2019-10-17 17:02:27
    复杂数学表达式的计算方法 : http://wangliguo.top:9995/swagger-ui.html#!/math45test45controller/spotScoreUsingGET
  • 使用Java数学表达式的值

    千次阅读 2018-08-17 21:05:15
    关于怎么求数学表达式的值,网上有很多教程。但大多教程只是一个Demo,该Demo只实现了个位数的四则运算,遇到个位数以上的计算时就会出现问题。本文在此基础上进行了扩展,实现了个位数以上的四则运算。 整体思路:...
  • Java计算数学表达式的结果的jar包(bsh-2.0b4.jar) Java计算数学表达式的结果的jar包(bsh-2.0b4.jar)
  • java 解析数学表达式

    千次阅读 2011-11-20 10:33:57
    数学表达式解析工具类: 支持负数运算, 多层括号嵌套运算   采用堆栈实现,实现步骤: (1)除去表达式中所有空白 (2)提取表达式运算符合 (3)依据运算符合,将表达式转化为一个数组 (4)对这个数组进行...
  • 业务中需要根据业务模板自动计算业务数据,采用jsexpression计算性能很差,因此需要自己实现。 直接上代码 ...import java.math.BigDecimal; import java.util.Objects; import java.util.Stack; import...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 57,938
精华内容 23,175
关键字:

java数学表达式

java 订阅