处理连续多个数据拼凑到某个数值

文章描述了一位开发者使用Java编写工具类,解决将多个包含日期和金额的JSON数据拼凑到与发票金额一致的问题,要求日期连续且金额差值尽量小。代码展示了如何遍历和计算这些数据以达到目标金额。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

处理连续多个数据拼凑到某个数值

最近因为要报销云资源测试费用,但是开发票的时候没有按照具体的资源开的,所以现在要把费用拼凑到和发票金额一致,为此写了一个Java工具类用于记录。大佬可以绕行,因为本人不是搞算法的,所以只是凭借自己理解写的。

  • 输入:带日期、金额的json数据,需要拼凑的金额
  • 输出:日期和金额差值
  • 要求:与输入的金额尽量相近,日期尽可能连续

代码如下:

public class TestUtil {
    public static void main(String[] args) {
        String s= "";
        Double target = 8000d;
        List<Kss> ksses = JSONArray.parseArray(s, Kss.class).stream().sorted(Comparator.comparing(Kss::getTime)).collect(Collectors.toList());
        Map<Integer, String> dateMap = new HashMap<>();
        Double[] d = new Double[ksses.size()];
        Double gg = 0d;
        for(int i = 0; i<ksses.size(); i++) {
            BigDecimal bd = new BigDecimal(ksses.get(i).getAccountPackageTotalCost()).setScale(2, RoundingMode.HALF_UP);
            d[i] = bd.doubleValue();
            if(i >= 74 && i <= 171) {
                gg += d[i];
            }
            dateMap.put(i, ksses.get(i).getTime());
        }
        toResult(d, dateMap, target);
    }

    public static void toResult(Double[] d, Map<Integer, String> dateMap, Double target){

        Double t = 8000d;
        Map<Double, String> map = new HashMap<>();
        List<Double> values = new ArrayList<>();
        for(int i = 0; i<d.length; i++){
            for(int j = 0; j<d.length; j++){
                Double f = 0d;
                if(i==j) {
                    f = d[i];
                } else if(i < j) {
                    for(int k=0; k<=(j-i); k++) {
                        f += d[i+k];
                    }
                } else {
                    continue;
                }
                Double h = 0d;
                if(f>t) {
                    h = f-t;
                }else {
                    h = t-f;
                }
                int oo = -1;
//                for(int r = 0; r<i; r++) {
//                    Double n = f + d[r];
//                    Double g = 0d;
//                    if(n>t) {
//                        g = n-t;
//                    }else {
//                        g = t-n;
//                    }
//                    if(g < h) {
//                        h = g;
//                        oo = r;
//                    }
//                }
//                for(int r = j+1; r<d.length; r++) {
//                    Double n = f + d[r];
//                    Double g = 0d;
//                    if(n>t) {
//                        g = n-t;
//                    }else {
//                        g = t-n;
//                    }
//                    if(g < h) {
//                        h = g;
//                        oo = r;
//                    }
//                }
                BigDecimal bd = new BigDecimal(h).setScale(2, RoundingMode.HALF_UP);
                h = bd.doubleValue();
                if(!map.containsKey(h)) {
                    map.put(h, i + "-" + j + (oo >= 0?"-"+oo:""));
                    values.add(h);
                }
            }
        }
        List<Double> sortedValues = values.stream().sorted().collect(Collectors.toList());
        for(int i = 0; i<100; i++) {
            Double ds = sortedValues.get(i);
            String[] v = map.get(ds).split("-");

            System.out.print("值:" + ds + ", ");
            System.out.print("值:" + v[0] + "--" + v[1]+",");
            System.out.print("值:" + dateMap.get(Integer.valueOf(v[0])) + "--" + dateMap.get(Integer.valueOf(v[1])));
            if(v.length == 3) {
                System.out.print("--" + dateMap.get(Integer.valueOf(v[2])));
            }
            System.out.println("");
        }
    }

    @Data
    public static class Kss {
        private String date;
        private String time;
        private Double accountPackageTotalCost;
    }
}
  • 运行结果如下:
  • 在这里插入图片描述
    第一列指与目标金额的差距
    第二列指需要累加的json数据
    第三列指日期
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值