将一个数随机拆分成多个整数

 1 /**
 2      * 将一个数随机拆分为多个整数
 3      * @param beans 最终结果集 默认null
 4      * @param num 补偿结果集 默认null
 5      * @param digital 需要拆分的数
 6      * @param fraction 需要拆分的份数
 7      * @param avg 拆分平均值 默认为null
 8      * @return
 9      */
10     private static List<Integer> distribution(Integer[] beans,Integer[] num,Integer digital, Integer fraction,Integer avg) {
11         //初始化 beans
12         if(ObjectUtils.isEmpty(beans)) {
13             beans = new Integer[fraction];
14             for (int i = 0; i < fraction; i++) {
15                 beans[i] = 0;
16             }
17         }
18         //初始化 avg
19         if(ObjectUtils.isEmpty(avg)) {
20             avg = digital/fraction;
21         }
22 
23         //创建大小为 fraction 的数组
24         num = new Integer[fraction];
25         //快速填充随机数,前fraction-1个参与分配
26         Integer reduce = 0 ;
27         for (int i = 0; i < fraction - 1; i++) {
28             num[i] = (int) Math.pow(Math.round(Math.random() * 1000), 1);
29             reduce += num[i];
30         }
31         //用于收集差值
32         num[fraction - 1] = 0;
33         //比例设置值
34         Integer sum = 0;
35         for (int i = 0; i < fraction - 1; i++) {
36             // BigDecimal.ROUND_DOWN 向下取整会导致最后一个值随着fraction增大而增大
37             num[i] = ((new BigDecimal(num[i])).multiply(new BigDecimal(digital)).divide(new BigDecimal(reduce), 0, BigDecimal.ROUND_DOWN)).intValue();
38             if(num[i] == 0) {
39                 num[i] = 1;
40             }
41             //不能提前 break 退出,需要处理完所有结果
42             if(sum +num[i]> digital) {
43                 num[i] = 0;
44             }
45             beans[i] += num[i];
46             sum += num[i];
47         }
48         //设置数组最后一个值
49         num[fraction - 1] = digital - sum;
50 
51         //如果最后一个值过大
52         if(num[fraction - 1]>avg) {
53             distribution(beans,num,num[fraction - 1], fraction,avg);
54         } else {
55             beans[fraction - 1] += num[fraction - 1];
56         }
57         //以 list 形式返回
58         return Arrays.asList(beans);
59     }
代码如下

 上一版代码有点小毛病,不能支撑百万量级的拆分,最新优化版如下:

 1 /**
 2      * 将一个数随机拆分为多个整数:
 3      * 1、取三分之一平均放入红包
 4      * 2、随机比例按顺序放入红包
 5      * @param beans 最终结果集 默认null
 6      * @param num 补偿结果集 默认null
 7      * @param digital 需要拆分的数
 8      * @param fraction 需要拆分的份数
 9      * @param avg 拆分平均值 默认为null
10      * @return
11      */
12     @Override
13     public List<Integer> distribution(Integer[] beans,Integer[] num,Integer digital, Integer fraction,Integer avg) {
14         //初始化 avg
15         if(ObjectUtils.isEmpty(avg)) {
16             avg = digital/fraction;
17         }
18         //初始化 beans
19         if(ObjectUtils.isEmpty(beans)) {
20             beans = new Integer[fraction];
21             int dvg = (avg/3)<1?1:(avg/3);
22             //平均填充
23             for (int i = 0; i < fraction; i++) {
24                 beans[i] = dvg;
25                 digital = digital-dvg;
26             }
27         }
28 
29         if(digital == 0) {
30             return  Arrays.asList(beans);
31         }
32 
33         //创建大小为 fraction 的数组
34         num = new Integer[fraction];
35         //快速填充随机数,前fraction-1个参与分配
36         Integer reduce = 1 ;
37         Random random = new Random();
38         for (int i = 0; i < fraction; i++) {
39             num[i] = random.nextInt(100)+1;
40             reduce += num[i];
41         }
42         //用于收集差值
43         num[fraction - 1] = 0;
44         //比例设置值
45         Integer sum = 0;
46         for (int i = 0; i < fraction - 1; i++) {
47             // BigDecimal.ROUND_DOWN 向下取整会导致最后一个值随着fraction增大而增大
48             num[i] = ((new BigDecimal(num[i])).multiply(new BigDecimal(digital)).divide(new BigDecimal(reduce), 0, BigDecimal.ROUND_DOWN)).intValue();
49             if(num[i] == 0) {
50                 num[i] = 1;
51             }
52             //不能提前 break 退出,需要处理完所有结果
53             if(sum +num[i]> digital) {
54                 num[i] = 0;
55             }
56             beans[i] += num[i];
57             sum += num[i];
58         }
59         //设置数组最后一个值
60         num[fraction - 1] = digital - sum;
61 
62         //如果最后一个值过大
63         if(num[fraction - 1]>avg) {
64             distribution(beans,num,num[fraction - 1], fraction,avg);
65         } else {
66             beans[fraction - 1] += num[fraction - 1];
67         }
68         //以 list 形式返回
69         return Arrays.asList(beans);
70     }

 

posted on 2021-08-20 09:47  instr  阅读(1354)  评论(0编辑  收藏  举报

导航