ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java实现计算最优现金优惠券组合

2021-08-10 13:04:47  阅读:143  来源: 互联网

标签:优惠券 java double list Item add new 最优 100


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,double,list,Item,add,new,最优,100
来源: https://www.cnblogs.com/dken/p/CalcDiscountCouponOptimalCombination.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有