1.适用场景
- 所有人抢得的金额总和等于红包总金额
- 抢得的红包至少有1分钱
2.算法设计细节
- 红包金额的单位设置为分
- 将发送的金额拆分为若干个红包保存
- 最后的返回值为整型数组
3.算法流程
公式:eachMoney = random(1,M/N * 2),其中M为剩余的总金额,N为未分配金额的红包个数,random()为随机数函数,其会返回[1,M/N * 2)中任意一个整数。
public class RedBagUtils {
/**
* 根据总金额和红包个数拆分为红包序列
*
* @param totalMoney
* @param moneyNum
* @return java.lang.Integer[]
* @author Tang
* @date 2023/8/26 17:03
**/
public static Integer[] generateReaBags(Integer totalMoney, Integer moneyNum) {
//总金额(单位为分)
int M = totalMoney;
//红包个数
int N = moneyNum;
//已分配的金额
int useMoney = 0;
Integer[] redBags = new Integer[N];
for (int i = 0; i < N; i++) {
if (i == N - 1) {
redBags[i] = M - useMoney;
break;
}
redBags[i] = new Random().nextInt((M - useMoney) / (N - i) * 2 - 1) + 1;
useMoney += redBags[i];
}
return redBags;
}
}
4.算法优势
使得红包金额的分布尽量接近均值。
5.算法运算过程
例如:现有一个5元的红包,需要拆分为5个
- 第一个红包:random(1,500/5 * 2),随机取值,取得73(分)
- 第二个红包:random(1,(500-73)/(5-1) * 2),随机取值,取得130(分)
- 第三个红包:random(1,(500-73-130)/(5-2) * 2),随机取值,取得62(分)
- 第四个红包:random(1,(500-73-130-62)/(5-3) * 2),随机取值,取得100(分)
- 第五个红包:最后一个红包,将剩下的金额全部分给它,为135(分)
(上述数据为某次测试的结果)