JAVA数学区间计算,支持开闭区间、百分比、-∞、+∞

发布时间:2024年01月12日


import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.math.BigDecimal;
import java.math.RoundingMode;


/**
 * 判断数值是否在数学区间范围内
 *
 * @author AnNong
 * @date 2023-04-07
 */
public class IntervalUtil {

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

    /**
     * @Description: 比较dataValue与interval结果
     * @Param: [dataValue:比较值, interval:如 ≤0、≥0 、>0 、<0 、==0]
     * @return: boolean
     */
    public static boolean compareNumValue(String dataValue, String interval) {
        //转换比较符号≤转换为<=,≥转换为>=
        String comparator = interval.replace("≤", "<=").replace("≥", ">=");
        //拼接表达式
        StringBuffer formula = new StringBuffer();
        formula.append("(");
        formula.append(dataValue);
        formula.append(comparator);
        formula.append(")");
        try {
            //计算表达式
            return (Boolean) jse.eval(formula.toString());
        } catch (Exception t) {
            return false;
        }
    }

    /**
     * 根据数学表达式计算结果
     *
     * @param expression 表达式, 70/(1.73*1.73)
     * @param scala      四舍五入保留几位小数
     * @return
     */
    public static String calcValue(String expression, int scala) {
        try {
            //计算表达式
            Object eval = jse.eval(expression);
            if (scala != 0) {
                BigDecimal result = new BigDecimal(eval.toString());
                result = result.setScale(2, RoundingMode.HALF_UP);
                return result.toString();
            }
            return String.valueOf(eval);
        } catch (Exception t) {
            return "";
        }
    }

    /**
     * 判断data_value是否在interval区间范围内
     *
     * @param data_value 数值类型的
     * @param interval   正常的数学区间,包括无穷大等,如:(1,3)、>5%、(-∞,6]、(125%,135%)U(70%,80%)
     * @return true:表示data_value在区间interval范围内,false:表示data_value不在区间interval范围内
     */
    public static boolean isInTheInterval(String data_value, String interval) {
        //将区间和data_value转化为可计算的表达式
        String formula = getFormulaByAllInterval(data_value, interval, "||");
        ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
        try {
            //计算表达式
            return (Boolean) jse.eval(formula);
        } catch (Exception t) {
            return false;
        }
    }


    /**
     * 将所有阀值区间转化为公式:如
     * [75,80)   =》        date_value < 80 && date_value >= 75
     * (125%,135%)U(70%,80%)   =》        (date_value < 1.35 && date_value > 1.25) || (date_value < 0.8 && date_value > 0.7)
     *
     * @param date_value
     * @param interval   形式如:(125%,135%)U(70%,80%)
     * @param connector  连接符 如:") || ("
     */
    private static String getFormulaByAllInterval(String date_value, String interval, String connector) {
        StringBuffer buff = new StringBuffer();
        for (String limit : interval.split("U")) {//如:(125%,135%)U (70%,80%)
            buff.append("(").append(getFormulaByInterval(date_value, limit, " && ")).append(")").append(connector);
        }
        String allLimitInvel = buff.toString();
        int index = allLimitInvel.lastIndexOf(connector);
        allLimitInvel = allLimitInvel.substring(0, index);
        return allLimitInvel;
    }

    /**
     * 将整个阀值区间转化为公式:如
     * 145)      =》         date_value < 145
     * [75,80)   =》        date_value < 80 && date_value >= 75
     *
     * @param date_value
     * @param interval   形式如:145)、[75,80)
     * @param connector  连接符 如:&&
     */
    private static String getFormulaByInterval(String date_value, String interval, String connector) {
        StringBuffer buff = new StringBuffer();
        for (String halfInterval : interval.split(",")) {//如:[75,80)、≥80
            buff.append(getFormulaByHalfInterval(halfInterval, date_value)).append(connector);
        }
        String limitInvel = buff.toString();
        int index = limitInvel.lastIndexOf(connector);
        limitInvel = limitInvel.substring(0, index);
        return limitInvel;
    }

    /**
     * 将半个阀值区间转化为公式:如
     * 145)      =》         date_value < 145
     * ≥80%      =》         date_value >= 0.8
     * [130      =》         date_value >= 130
     * <80%     =》         date_value < 0.8
     *
     * @param halfInterval 形式如:145)、≥80%、[130、<80%
     * @param date_value
     * @return date_value < 145
     */
    private static String getFormulaByHalfInterval(String halfInterval, String date_value) {
        halfInterval = halfInterval.trim();
        if (halfInterval.contains("∞")) {//包含无穷大则不需要公式
            return "1 == 1";
        }
        StringBuffer formula = new StringBuffer();
        String data = "";
        String opera = "";
        if (halfInterval.matches("^([<>≤≥\\[\\(]{1}(-?\\d+.?\\d*\\%?))$")) {//表示判断方向(如>)在前面 如:≥80%
            opera = halfInterval.substring(0, 1);
            data = halfInterval.substring(1);
        } else {//[130、145)
            opera = halfInterval.substring(halfInterval.length() - 1);
            data = halfInterval.substring(0, halfInterval.length() - 1);
        }
        double value = dealPercent(data);
        formula.append(date_value).append(" ").append(opera).append(" ").append(value);
        String a = formula.toString();
        //转化特定字符
        return a.replace("[", ">=").replace("(", ">").replace("]", "<=").replace(")", "<").replace("≤", "<=").replace("≥", ">=");
    }

    /**
     * 去除百分号,转为小数
     *
     * @param str 可能含百分号的数字
     * @return
     */
    private static double dealPercent(String str) {
        double d = 0.0;
        if (str.contains("%")) {
            str = str.substring(0, str.length() - 1);
            d = Double.parseDouble(str) / 100;
        } else {
            d = Double.parseDouble(str);
        }
        return d;
    }

    public static void main(String[] args) {
        // 年龄大于等于35岁或小于等于18岁
//        String c = "(-∞,18]U[35,+∞)";
//        System.out.println(isInTheInterval("36", c));
//        System.out.println(isInTheInterval("18", c));
//        System.out.println(isInTheInterval("17", c));

        ScriptEngine jse = new ScriptEngineManager().getEngineByName("JavaScript");
        try {
            //计算表达式
            String e = "70/(1.73*1.73)";
            System.out.println(jse.eval(e));
        } catch (Exception t) {
            t.printStackTrace();
        }
//
//
//        String d = "[40,+∞)";
//        System.out.println(isInTheInterval("40", c));
//        System.out.println(isInTheInterval("41", c));
//
//        //判断区间范围
//        System.out.println(isInTheInterval("2", "(1,3]"));
        //比较dataValue与interval结果
    }


}

文章来源:https://blog.csdn.net/AdminC/article/details/135555392
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。