将一个数随机拆分成多个整数
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 }