Java通过String类型计算公式,算出结果值

Java通过String类型计算公式,算出结果值


需求:(通过数据库取出计算公式,在获取数据值计算结果)
各类公式集合

实现方法(独立方法,可以直接使用):

 static ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");

 /*    公式格式和数据格式
          countmode = "R=(M/N)×100%;M=A+B;N=C+D";
          map.put("A", "2");
          map.put("B", "1");
          map.put("C", "2");
          map.put("D", "1");
          */
    public String calculation(String countmode, Map map) {

        //判断是否存在公式
        if (StringUtils.isBlank(countmode)) {
            return "";
        }
        //结果值
        String vaule = "";

        //判断公式是否只是简单的=值
        char[] chars = countmode.toCharArray();
        if (chars.length == 3) {
            for (Object key : map.keySet()) {
                Object a = map.get(key);
                vaule = String.valueOf(a);
            }
            return vaule;
        }

        //判断公式中是否存在百分号
        boolean symbol = false;
        //判断公式中是否存在冒号
        boolean colon = false;
        String colonVaule = "";

        //处理特殊符号
        countmode = countmode.replaceAll("(", "(");
        countmode = countmode.replaceAll(")", ")");
        countmode = countmode.replaceAll("×", "*");
        countmode = countmode.replaceAll("\\{", "[");
        countmode = countmode.replaceAll("}", "]");
        String regEx = "[%]";
        Pattern compile = Pattern.compile(regEx);
        Matcher matcher = compile.matcher(countmode);
        if (matcher.find()) {
            symbol = true;
            countmode = countmode.replaceAll("%", "");
        }
        //多个公式返回数组
        String[] countmodes = countmode.split(";");

        try {
            //判断是否需要多次计算
            if (countmodes.length == 1) {
                //获取计算公式
                String equalationRight = countmode.split("=")[1];

                //判断公式中是否存在结果之间的互比
                String regExs = "[:]";
                Pattern compiles = Pattern.compile(regExs);
                Matcher matchers = compiles.matcher(countmode);
                if (matchers.find()) {
                    colon = true;
                    colonVaule = equalationRight.split(":")[0];
                    equalationRight = equalationRight.split(":")[1];
                }

                //获取计算公式字母,用于取值
                char[] split = equalationRight.replaceAll("[^A-Za-z]", "").toCharArray();
                for (char s : split) {
                    String key = String.valueOf(s);
                    String val = DwuObject.valString(key, map);
                    //值为空则设置为0
                    if (StringUtils.isBlank(val)) {
                        val = "0";
                    }
                    //将值替换到公式中
                    equalationRight = equalationRight.replaceAll(key, val);
                }
                Object eval = jse.eval(equalationRight);
                vaule = String.valueOf(eval);
                //当被除数、除数都为0的情况和被除数为0的情况直接返回0
                if (vaule.equals("NaN") || vaule.equals("Infinity")) {
                    return "0";
                }
                if (symbol) {
                    vaule = vaule + "%";
                }
                if (colon) {
                    vaule = colonVaule + ":" + vaule;
                }
            } else {
                for (int i = countmodes.length - 1; i >= 0; i--) {
                    //计算结果代表字母,用于多次计算取值
                    String equalationKey = countmodes[i].split("=")[0];
                    //获取计算公式
                    String equalationRight = countmodes[i].split("=")[1];
                    //获取计算公式字母,用于取值
                    char[] split = equalationRight.replaceAll("[^A-Za-z]", "").toCharArray();
                    for (char s : split) {
                        String key = String.valueOf(s);
                        String val = DwuObject.valString(key, map);
                        //值为空则设置为0
                        if (StringUtils.isBlank(val)) {
                            val = "0";
                        }
                        //将值替换到公式中
                        equalationRight = equalationRight.replaceAll(key, val);
                    }
                    Object eval = jse.eval(equalationRight);
                    vaule = String.valueOf(eval);
                    //当被除数、除数都为0的情况和被除数为0的情况直接返回0
                    if (vaule.equals("NaN") || vaule.equals("Infinity")) {
                        return "0";
                    }
                    //最后一次计算
                    if (i == 0) {
                        if (symbol) {
                            vaule = vaule + "%";
                        }
                    } else {
                        map.put(equalationKey, vaule);
                    }
                }
            }
        } catch (Exception t) {

        }
        return vaule;
    }

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值