红包分配问题
红包分配问题给你一个整数表示红包的总额,和另一个整数表示红包的个数
表示我们要把总金额,随机分成N个红包。
要求1:每个红包的金额都是随机的
要求2:每个人至少1分钱
示例代码:
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;//红包剩余金额,因为每个红包的最小金额为1分,所以可以把每个红包的初始量设为1分
18 int[] luckMoney=new int;
19 Random r = new Random();
20 for (int i = 0; i < luckMoney.length; i++) {
21 if (i==luckMoney.length-1){//最后一个红包金额等于红包金额的最后剩余量+1分
22 luckMoney=1+rest;
23 break;
24 }
25 if (rest>0){
26 int temp=r.nextInt(rest+1);//
27 luckMoney=1+temp;
28 rest-=temp;
29 }else {//红包剩余金额已经分配完了,剩余红包的金额都为1分
30 luckMoney=1;
31 }
32 }
33 BigDecimal[] luckMoney1=new BigDecimal;//这里用BigDecimal数组来记录红包的金额,因为BigDecimal进行计算时不会丢失精度
34 //BigDecimal sum = new BigDecimal("0");
35 for (int i = 0; i < luckMoney.length; i++) {
36 BigDecimal a = new BigDecimal(""+luckMoney);
37 BigDecimal b = new BigDecimal("100");
38 luckMoney1= a.divide(b,2,BigDecimal.ROUND_HALF_UP);//转化以元为单位时,除以100,应保留两位小数
39 sum=sum.add(luckMoney1);
40 }
41 //System.out.println(sum);
42 return luckMoney1;
43 }
44 }运行结果:
这个算法虽然能达到随机分配红包金额的功能,但由上面运行结果我们不难发现,越往后红包分配的可金额越小,而且红包分配不够均匀
为了保证每个红包金额分配额度的合理,
额度应该在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;
20 Random r = new Random();
21 for (int i = 0; i < luckMoney.length; i++) {
22 if (i==luckMoney.length-1){
23 luckMoney=1+rest;
24 break;
25 }
26 if (rest>0){
27 int temp=r.nextInt(rest*2/restNum+1);//修改处
28 restNum--;
29 luckMoney=1+temp;
30 rest-=temp;
31 }else {
32 luckMoney=1;
33 }
34 }
35 BigDecimal[] luckMoney1=new BigDecimal;
36 BigDecimal sum = new BigDecimal("0");
37 for (int i = 0; i < luckMoney.length; i++) {
38 BigDecimal a = new BigDecimal(""+luckMoney);
39 BigDecimal b = new BigDecimal("100");
40 luckMoney1= a.divide(b,2,BigDecimal.ROUND_HALF_UP);
41 sum=sum.add(luckMoney1);
42 }
43 System.out.println(sum);
44 return luckMoney1;
45 }
46 }运行结果:
在红包拆开之前,每个人,无论先后顺序,抢到的红包金额的数学期望都是一样的,如果100元分成5个红包,那么每个人抢到的金额的数学期望就是20元,但有趣的是,虽然数学期望一样,但概率密度却有很大差别。如果想详细了解红包分配的问题可以阅读这篇知乎文献:微信红包金额分配的算法是怎样的?谁比较容易到最佳手气?谁有机会拿到较大的金额? - Jingchi Wang的回答 - 知乎 https://www.zhihu.com/question/28250396/answer/86302251
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页:
[1]