java实现计算最优现金优惠券组合
2021/8/10 14:05:54
本文主要是介绍java实现计算最优现金优惠券组合,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
java实现计算最优现金优惠券组合
在众多可叠加现金类型优惠券中(比如100减5,200减12等),选出可打折金额最大的组合。
下面代码
package com.dk.common.util.algo; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * * 计算最优优惠券组合 * */ public class CalcDiscountCouponOptimalCombination { /// ***** 测试 public static void main(String[] args) { double max = 600; List<Item> list = new ArrayList<>(); list.add(new Item(100, 2)); list.add(new Item(100, 3)); list.add(new Item(300, 3)); list.add(new Item(300, 9)); list.add(new Item(300, 4)); list.add(new Item(200, 4)); list.add(new Item(100, 2)); list.add(new Item(200, 9)); list.add(new Item(300, 4)); list.add(new Item(100, 3)); list.add(new Item(230, 3)); list.add(new Item(300, 3)); list.add(new Item(500, 9)); list.add(new Item(300, 4)); list.add(new Item(100, 4)); list.add(new Item(100, 2)); list.add(new Item(400, 9)); list.add(new Item(300, 4)); list.add(new Item(100, 3)); list.add(new Item(230, 3)); for (int i = 0; i < 5; i++) { list.add(new Item(300, 3)); list.add(new Item(500, 9)); list.add(new Item(300, 4)); list.add(new Item(100, 4)); list.add(new Item(100, 2)); list.add(new Item(400, 9)); list.add(new Item(300, 4)); list.add(new Item(100, 3)); list.add(new Item(230, 3)); list.add(new Item(230, 3)); } // ************************ // 券数量多的,建议先按“折扣限制”从大到小排序,可以减少逻辑计算时间 list.sort((o1, o2) -> o1.deduct == o2.deduct ? 0 : o1.deduct > o2.deduct ? -1 : 1); Map<String, Double> maxReduceIdxIssMap = calcMaxReduceIdxIssMap(list, max); System.out.println(maxReduceIdxIssMap); for (String idxIss : maxReduceIdxIssMap.keySet()) { System.out.println("-------------------------------------"); System.out.println(idxIss); String[] idxIsArr = idxIss.split(""); for (int idx = 0; idx < idxIsArr.length; idx++) { String is = idxIsArr[idx]; if ("1".equals(is)) { System.out.println(idx + ": " + list.get(idx)); } } } } /** * 计算最大优惠组合列表 */ public static Map<String, Double> calcMaxReduceIdxIssMap(List<Item> list, double maxAstrict) { Map<String, Double> maxReduceIdxIssMap = new HashMap<>();// 统计极限组合 int len = list.size(); LoopRear lr = new LoopRear() { double currMaxReduce = 0; // idxIss 由0、1组成,1所在下标表示对应项参与了此组合 @Override public boolean runRear(int start, String idxIss, double deductSum, double reduceSum) { boolean haveRear = false;// 后面流程有没有符合条件的子类组合 String pad = "1"; for (int i = start; i < len; i++) { Item item = list.get(i); double currDeductSum = deductSum + item.deduct;// 当前组合折扣限制总和 double currReduceSum = reduceSum + item.reduce;// 当前组合折扣额度总和 if (currDeductSum <= maxAstrict) { haveRear = true;// 当前组合限制总和小于总金额,表示当前组合的父类不是极限组合(存在子类组合) String currIdxIss = idxIss + pad; boolean haveRearRear = this.runRear(i + 1, currIdxIss, currDeductSum, currReduceSum);// 是否存在子类组合 if (!haveRearRear) { // 不存在子类组合,表示当前组合为一个极限组合 // 比对之前的折扣金额,只保留最大折扣金额的 if (currReduceSum > currMaxReduce) { currMaxReduce = currReduceSum; maxReduceIdxIssMap.clear(); maxReduceIdxIssMap.put(currIdxIss, currReduceSum); } else if (currReduceSum == currMaxReduce) { maxReduceIdxIssMap.put(currIdxIss, currReduceSum); } } } pad = "0" + pad;// 前面下标的项不参与之后组合,后移一位 } return haveRear; } }; lr.runRear(0, "", 0, 0);// 从第一个开始执行 return maxReduceIdxIssMap; } public static class Item { protected double deduct;// 折扣限制,折扣条件 protected double reduce;// 折扣额度 public Item(double deduct, double reduce) { super(); this.deduct = deduct; this.reduce = reduce; } @Override public String toString() { return reduce + "[" + deduct + "]"; } } protected interface LoopRear { boolean runRear(int start, String idxIss, double deductSum, double reduceSum); } }
这篇关于java实现计算最优现金优惠券组合的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略