【纯java代码实现字符串运算符或公式计算,支持函数,不借助第三方依赖、工具】

2024-01-03 09:19:31

纯java代码实现字符串运算符或公式计算,支持函数,不借助第三方依赖和工具

效果图

在这里插入图片描述

代码

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zwb
 * @version 1.0
 * @Date 2024/1/2
 * @Description: 字符串公式计算
 * @Description: 支持运算符:加减乘除,等于,不等于,大于,小于,大于等于,小于等于
 * @Description: 支持函数:IF(,,),SUM(),AVG(),ABS(),MAX(),MIN()
 */
public class StrFormulaUtil {


    public static void main(String[] args) {
        String str = "";
        //加减乘除
        str = "1*(5-3)/2";
        System.out.println(str+"的运算结果为:"+initResult(str));
        //IF(条件,真值,假值)条件函数
        str = "20-IF(1>=2,5,6)";
        System.out.println(str+"的运算结果为:"+initResult(str));
        //SUM(值,值,值)求和函数
        str = "20-SUM(1,2,3,4,5)";
        System.out.println(str+"的运算结果为:"+initResult(str));
        //AVG(值,值,值)平均值函数
        str = "20-AVG(2,4,8,2)";
        System.out.println(str+"的运算结果为:"+initResult(str));
        //MAX(值,值,值)最大值函数
        str = "20-MAX(1,2,3,4,5)";
        System.out.println(str+"的运算结果为:"+initResult(str));
        //MIN(值,值,值)最小值函数
        str = "20-MIN(1,2,3,4,5)";
        System.out.println(str+"的运算结果为:"+initResult(str));
    }


    /**
     * @author zwb
     * @param info
     * @Description: 公式计算获取结果
     */
    public static String initResult(String info){
        return initBracket("("+info+")");
    }

    /**
     * @author zwb
     * @param str
     * @Description: 核心计算模块
     */
    public static String initNum(String str){
        String symbol[] = {"+","-","*","/",">","<","=","!=",">=","<="};
        int add = str.indexOf("+");
        int subtract = str.indexOf("-");
        if (subtract!=-1){
            String num="";
            if (subtract-1>=0){
                num = str.substring(subtract-1, subtract);
                try {
                    Integer.parseInt(num);
                } catch(NumberFormatException e) {
                    subtract=-1;
                }
            }else {
                subtract=-1;
            }
        }
        int multiply = str.indexOf("*");
        int divide = str.indexOf("/");
        int dy = str.indexOf(">");
        int xy = str.indexOf("<");
        int dd = str.indexOf("=");
        int bdd = str.indexOf("!=");
        int dyd = str.indexOf(">=");
        int xyd = str.indexOf("<=");
        int i=0;
        int j=0;
        if (multiply==-1&&divide==-1&&add==-1&&subtract==-1&&dy==-1&&xy==-1&&dd==-1&&dyd==-1&&xyd==-1){
            return str;
        }
        if (multiply!=-1||divide!=-1){
            j=1;
            i=(multiply==-1)?divide:((divide==-1)?multiply:(multiply<divide?multiply:divide));
        }else if (add!=-1||subtract!=-1){
            j=1;
            i=(add==-1)?subtract:((subtract==-1)?add:(add<subtract?add:subtract));
        }else if (bdd!=-1||dyd!=-1||xyd!=-1){
            j=2;
            Integer index[] = {bdd,dyd,xyd};
            List<Integer> indexList = Arrays.asList(index).stream().filter(x->x!=-1).collect(Collectors.toList());
            i= Collections.min(indexList);
        }else if (dy!=-1||xy!=-1||dd!=-1){
            j=1;
            Integer index[] = {dy,xy,dd};
            List<Integer> indexList = Arrays.asList(index).stream().filter(x->x!=-1).collect(Collectors.toList());
            i=Collections.min(indexList);
        }
        String strs = "";
        if (Arrays.asList(symbol).contains(str.substring(i,i+j))){
            String regex = "[\\+\\-\\*/><=(!=)(>=)(<=)]";
            String left = str.substring(0, i);
            String right = str.substring(i+j, str.length());
            String[] lefts = left.split(regex);
            String[] rights = right.split(regex);
            if ("-".equals(right.charAt(0)+"")){
                rights=right.substring(1).split(regex);
                rights[0] = "-"+rights[0];
            }
            String leftStr = left.substring(0,left.length()-lefts[lefts.length - 1].length());
            String rightStr = right.substring(rights[0].length(),right.length());
            if ("*".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+leftNum.multiply(rightNum)+rightStr;
            }else if ("/".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+leftNum.divide(rightNum,4,BigDecimal.ROUND_HALF_UP)+rightStr;
            }else if ("+".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+leftNum.add(rightNum)+rightStr;
            }else if ("-".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+leftNum.subtract(rightNum)+rightStr;
            }else if ("!=".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+(leftNum.compareTo(rightNum)!=0)+rightStr;
            }else if (">=".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+(leftNum.compareTo(rightNum)>=0)+rightStr;
            }else if ("<=".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+(leftNum.compareTo(rightNum)<=0)+rightStr;
            }else if (">".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+(leftNum.compareTo(rightNum)>0)+rightStr;
            }else if ("<".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+(leftNum.compareTo(rightNum)<0)+rightStr;
            }else if ("=".equals(str.substring(i,i+j))){
                BigDecimal leftNum = new BigDecimal(lefts[lefts.length - 1]);
                BigDecimal rightNum = new BigDecimal(rights[0]);
                strs = leftStr+(leftNum.compareTo(rightNum)==0)+rightStr;
            }else {
                strs = left+str.substring(i,i+j)+right;
            }
        }
        boolean flag = false;
        for (String item : Arrays.asList(symbol)) {
            if (strs.contains(item)){
                flag = true;
            }
        }
        if (flag){
            strs = initNum(strs);
        }
        return strs;
    }


    /**
     * @author zwb
     * @param info,select
     * @Description: 指定字符出现的下标抓取
     */
    public static List<Integer> getStrToIndexOf(String info,String select){
        //记录出现的位置
        List<Integer> countList = new ArrayList<>();
        if (info==null){
            return countList;
        }
        //从最前方开始检索
        int start = 0;
        //获取检索字符长度
        int index = select.length();
        while (true) {
            if (info.indexOf(select, start) != -1) {
                //找到对应字符所在索引,当找到后,将下次寻找的位置转换到当前已找到的位置
                start = info.indexOf(select, start);
                countList.add(start);
                //改变下次检索位置 如:yelloye 从索引0开始查找ye,找到后start = 0;则下次从索引2开始检索(即l处)
                start += index; //涉及到多个字符时比 start++检索速度快
            } else {
                break;
            }
        }
        return countList;
    }


    /**
     * @author zwb
     * @param body
     * @Description: 公式核心拆解方法
     */
    public static String initBracket(String body){
        List<Integer> startList = getStrToIndexOf(body, "(");
        List<Integer> endList = getStrToIndexOf(body, ")");
        Integer end = endList.get(0);
        Integer start = Collections.max(startList.stream().filter(s -> s < end).collect(Collectors.toList()));
        String left = body.substring(0,start);
        String right = body.substring(end+1,body.length());
        String middle = body.substring(start+1,end);
        if (left.length()>=2&&"IF".equals(left.substring(left.length()-2,left.length()))){//IF函数
            middle = initIf(middle);
            left = left.substring(0,left.length()-2);
        }else if (left.length()>=3&&"SUM".equals(left.substring(left.length()-3,left.length()))){//SUM函数
            middle = initSUM(middle);
            left = left.substring(0,left.length()-3);
        }else if (left.length()>=3&&"AVG".equals(left.substring(left.length()-3,left.length()))){//AVG函数
            middle = initAVG(middle);
            left = left.substring(0,left.length()-3);
        }else if (left.length()>=3&&"ABS".equals(left.substring(left.length()-3,left.length()))){//ABS函数
            middle = initABS(middle);
            left = left.substring(0,left.length()-3);
        }else if (left.length()>=3&&"MAX".equals(left.substring(left.length()-3,left.length()))){//MAX函数
            middle = initMAX(middle);
            left = left.substring(0,left.length()-3);
        }else if (left.length()>=3&&"MIN".equals(left.substring(left.length()-3,left.length()))){//MIN函数
            middle = initMIN(middle);
            left = left.substring(0,left.length()-3);
        }else {
            middle = initNum(middle);
        }
        String content = left+middle+right;
        if (content.indexOf("(")!=-1||content.indexOf(")")!=-1){
            content = initBracket(content);
        }
        return content;
    }


    /**
     * @author zwb
     * @param str
     * @Description: IF(条件,真值,假值)函数计算
     * @Description: 判断条件是否成立,成立则取第一个值,不成立则取第二个值
     */
    public static String initIf(String str){
        String[] split = str.split(",");
        String condition = initNum(split[0]);
        String trueValue = initNum(split[1]);
        String falseValue = initNum(split[2]);
        if ("true".equals(condition)){
            return trueValue;
        }
        if ("false".equals(condition)){
            return falseValue;
        }
        if (Integer.valueOf(condition)>0){
            return trueValue;
        }else {
            return falseValue;
        }
    }

    /**
     * @author zwb
     * @param str
     * @Description: SUM(值,值,值)函数计算
     * @Description: 求所有值的和
     */
    public static String initSUM(String str){
        String[] split = str.split(",");
        BigDecimal sumAmount = new BigDecimal(0);
        for (String s : split) {
            sumAmount=sumAmount.add(new BigDecimal(initNum(s)));
        }
        return sumAmount.toString();
    }

    /**
     * @author zwb
     * @param str
     * @Description: ABG(值,值,值)函数计算
     * @Description: 求所有值的平均值
     */
    public static String initAVG(String str){
        String[] split = str.split(",");
        BigDecimal sumAmount = new BigDecimal(0);
        for (String s : split) {
            sumAmount=sumAmount.add(new BigDecimal(initNum(s)));
        }
        return sumAmount.divide(new BigDecimal(split.length),4,BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * @author zwb
     * @param str
     * @Description: ABG(值)函数计算
     * @Description: 求数字的绝对值
     */
    public static String initABS(String str){
        double abs = Math.abs(Double.valueOf(initNum(str)));
        return abs+"";
    }

    /**
     * @author zwb
     * @param str
     * @Description: MAX(值,值,值)函数计算
     * @Description: 求出最大值
     */
    public static String initMAX(String str){
        String[] split = str.split(",");
        BigDecimal maxAmount = new BigDecimal(0);
        for (String s : split) {
            if (new BigDecimal(initNum(s)).compareTo(maxAmount)>0){
                maxAmount = new BigDecimal(initNum(s));
            }
        }
        return maxAmount.toString();
    }

    /**
     * @author zwb
     * @param str
     * @Description: MIN(值,值,值)函数计算
     * @Description: 求出最小值
     */
    public static String initMIN(String str){
        String[] split = str.split(",");
        BigDecimal minAmount = new BigDecimal(initNum(split[0]));
        for (String s : split) {
            if (new BigDecimal(initNum(s)).compareTo(minAmount)<0){
                minAmount = new BigDecimal(initNum(s));
            }
        }
        return minAmount.toString();
    }
}

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