红包分配问题

316 阅读2分钟

后端工程师的高阶面经 下栽: www.sanzhishu.top/1029.html


给你一个整数表示红包的总额,和另一个整数表示红包的个数

表示我们要把总金额,随机分成N个红包。

要求1:每个红包的金额都是随机的

要求2:每个人至少1分钱

示例代码:

运行结果:

这个算法虽然能达到随机分配红包金额的功能,但由上面运行结果我们不难发现,越往后红包分配的可金额越小,而且红包分配不够均匀

为了保证每个红包金额分配额度的合理,

额度应该在0.01和剩余平均值×2之间。例如:发100块钱,总共10个红包,那么平均值是10块钱一个,那么发出来的红包的额度在0.01元~20元之间波动。 当前面3个红包总共被领了40块钱时,剩下60块钱,总共7个红包,那么这7个红包的额度在:0.01~(60/7×2)=17.14之间。

修改后的代码为

 1 public class Test2 {
 2     public static void main(String[] args) {
 3         System.out.println(Arrays.toString(luckyMoney("150.01", 10)));
 4     }
 5
 6     public static BigDecimal[] luckyMoney(String money,int n){
 7         double money1= 0;
 8         try {
 9             money1 = Double.parseDouble(money);
10         } catch (NumberFormatException e) {
11             System.out.println("输入金额错误!");
12             e.printStackTrace();
13             return null;
14         }
15         System.out.println(money1);
16         int total=(int) (money1*100);
17         int rest=total-n;
18         int restNum=n;//剩余红包个数
19         int[] luckMoney=new int[n];
20         Random r = new Random();
21         for (int i = 0; i < luckMoney.length; i++) {
22             if (i==luckMoney.length-1){
23                 luckMoney[luckMoney.length-1]=1+rest;
24                 break;
25             }
26             if (rest>0){
27                 int temp=r.nextInt(rest*2/restNum+1);//修改处
28                 restNum--;
29                 luckMoney[i]=1+temp;
30                 rest-=temp;
31             }else {
32                 luckMoney[i]=1;
33             }
34         }
35         BigDecimal[] luckMoney1=new BigDecimal[n];
36         BigDecimal sum = new BigDecimal("0");
37         for (int i = 0; i < luckMoney.length; i++) {
38             BigDecimal a = new BigDecimal(""+luckMoney[i]);
39             BigDecimal b = new BigDecimal("100");
40             luckMoney1[i]= a.divide(b,2,BigDecimal.ROUND_HALF_UP);
41             sum=sum.add(luckMoney1[i]);
42         }
43         System.out.println(sum);
44         return luckMoney1;
45     }
46 }

运行结果:

[7.21, 30.82, 26.08, 21.54, 7.81, 22.19, 9.72, 15.15, 3.89, 5.60]

在红包拆开之前,每个人,无论先后顺序,抢到的红包金额的数学期望都是一样的,如果100元分成5个红包,那么每个人抢到的金额的数学期望就是20元,但有趣的是,虽然数学期望一样,但概率密度却有很大差别。如果想详细了解红包分配的问题可以阅读这篇知乎文献:微信红包金额分配的算法是怎样的?谁比较容易到最佳手气?谁有机会拿到较大的金额? - Jingchi Wang的回答 - 知乎 www.zhihu.com/question/28…

关注夏壹分享发送:资源 获取深入讲解JVM虚拟机课程