package com.example.ant.common.tools; import java.util.LinkedList; import java.util.List; /** * 描述:紅包算法 * User: 曾遠征 * Date: 2018-09-17 * Time: 14:09 */ public class RedPacketTools { /** * 生成紅包最小值 1分 */ private static final int MIN_MONEY = 1; /** * 生成紅包最大值 200人民幣 */ private static final int MAX_MONEY = 200 * 100; /** * 小於最小值 */ private static final int LESS = -1; /** * 大於最大值 */ private static final int MORE = -2; /** * 正常值 */ private static final int OK = 1; /** * 最大的紅包是平均值的 TIMES 倍,防止某一次分配紅包較大 */ private static final double TIMES = 2.1F; private int recursiveCount = 0; private List<Integer> splitRedPacket(int money, int count) { List<Integer> moneys = new LinkedList<>(); //計算出最大紅包 int max = (int) ((money / count) * TIMES); max = max > MAX_MONEY ? MAX_MONEY : max; for (int i = 0; i < count; i++) { //隨機獲取紅包 int redPacket = randomRedPacket(money, MIN_MONEY, max, count - i); moneys.add(redPacket); //總金額每次減小 money -= redPacket; } return moneys; } private int randomRedPacket(int totalMoney, int minMoney, int maxMoney, int count) { //只有一個紅包直接返回 if (count == 1) { return totalMoney; } if (minMoney == maxMoney) { return minMoney; } //若是最大金額大於了剩餘金額 則用剩餘金額 由於這個 money 每分配一次都會減少 maxMoney = maxMoney > totalMoney ? totalMoney : maxMoney; //在 minMoney到maxMoney 生成一個隨機紅包 int redPacket = (int) (Math.random() * (maxMoney - minMoney) + minMoney); int lastMoney = totalMoney - redPacket; int status = checkMoney(lastMoney, count - 1); //正常金額 if (OK == status) { return redPacket; } //若是生成的金額不合法 則遞歸從新生成 if (LESS == status) { recursiveCount++; System.out.println("recursiveCount==" + recursiveCount); return randomRedPacket(totalMoney, minMoney, redPacket, count); } if (MORE == status) { recursiveCount++; System.out.println("recursiveCount===" + recursiveCount); return randomRedPacket(totalMoney, redPacket, maxMoney, count); } return redPacket; } /** * 校驗剩餘的金額的平均值是否在 最小值和最大值這個範圍內 * * @param lastMoney * @param count * @return */ private int checkMoney(int lastMoney, int count) { double avg = lastMoney / count; if (avg < MIN_MONEY) { return LESS; } if (avg > MAX_MONEY) { return MORE; } return OK; } public static void main(String[] args) { RedPacketTools redPacket = new RedPacketTools(); List<Integer> redPackets = redPacket.splitRedPacket(20000, 100); System.out.println(redPackets); int sum = 0; for (Integer red : redPackets) { sum += red; } System.out.println(sum); } }