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

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

最近因为要报销云资源测试费用,但是开发票的时候没有按照具体的资源开的,所以现在要把费用拼凑到和发票金额一致,为此写了一个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数据
    第三列指日期
在MATLAB中,如果你已经有一系列的小区间,并想要通过合并它们来形成一系列大的区间,以达到最优化的目的(例如,最小化区间数或最大化覆盖),可以使用贪心策略或者动态规划方法。这里我们以简化版的思路为例,假设我们要找到覆盖所有数字的一组区间,使得区间数量最少: ```matlab function optimalIntervals = mergeIntervals(intervals) intervals = sortrows(intervals, 'Start'); % 按起始位置排序 optimalIntervals = {}; lastEnd = intervals(1, 'End'); % 初始区间为第一个区间 for i = 2:size(intervals, 1) % 检查当前区间是否能够与上一个区间相连 if intervals(i, 'Start') <= lastEnd lastEnd = max(lastEnd, intervals(i, 'End')); % 更新最后一个区间的结束位置 else % 否则创建一个新的区间并添加到结果列表 optimalIntervals{end+1} = {'[', num2str(intervals(1, 'Start')), ':', num2str(lastEnd), ']'}; lastEnd = intervals(i, 'End'); % 更新lastEnd为新的区间结束 end end % 处理最后一个区间 optimalIntervals{end+1} = {'[', num2str(intervals(end, 'Start')), ':', num2str(lastEnd), ']'}; % 返回结果 optimalIntervals = cellfun(@(x) strjoin({'[' x ']'}, ' '), optimalIntervals, 'UniformOutput', false); end % 示例: intervals = [1:4, 6:8, 9:12, 15:17]; mergedIntervals = mergeIntervals(intervals) ``` 这个函数会返回一个字符串向量,每个元素表示一个区间,比如`{'[1:4]'}`,`{'[6:8]'}`等。这仅是最基础的版本,实际问题可能更复杂,涉及优先级队列、回溯搜索或其他算法,具体取决于你的优化目标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值