将一个数M随机分为N份,并限制每份的大小
需求场景:
-在活动开发中将50000个金币分为1000个金币红包,每个红包数额在8~188之间。
实现代码:
/**
* 将一个数M随机分为N份,并限制每份的大小
* @param totalNum 总金币数
* @param count 分成的数量
* @param leftNum 区间的极小值(包含)
* @param rightNum 区间的极大值(包含)
* @return
* @author lei.yan004
*/
public List<Integer> randomAlloter(int totalNum, int count, int leftNum, int rightNum) {
if (count * rightNum < totalNum) {
// 总金币数不能大于极大值*数量,否则无法将金币分完,造成死循环
totalNum = count * rightNum;
}
if (count * leftNum > totalNum) {
// 总金币数不能小于极小值*数量,否则无法将金币将不足,造成死循环
totalNum = count * leftNum;
}
int useNum = 0;// 使用的数量
List<Integer> list = new ArrayList<Integer>();
// 随机生成count个
for (int i = 0; i < count; i++) {
int round = (int) Math.round(Math.random() * (rightNum - leftNum) + leftNum);
useNum += round;
list.add(round);
}
int random = 0;
int item = 0;
if (useNum > totalNum) {
while (useNum != totalNum) {
random = (int) (Math.random() * count);
item = list.get(random);
if (item - 1 < leftNum) {
continue;
}
if (useNum <= totalNum) {
break;
}
useNum--;
list.set(random, item - 1);
}
}
if (useNum < totalNum) {
while (useNum != totalNum) {
random = (int) (Math.random() * count);
item = list.get(random);
if (item + 1 > rightNum) {
continue;
}
if (useNum >= totalNum) {
break;
}
useNum++;
list.set(random, item + 1);
}
}
return list;
}
** 测试 :**
@Test
public void test() {
Set<String> set = new HashSet<String>();
List<Integer> list = randomAlloter(100000, 1000, 8, 188);
System.out.println("总数据个数:"+list.size());
int a = 0;
for (Integer integer : list) {
if(integer>188||integer<8){
System.out.println("超出边界值:"+integer);
}
if(integer==8||integer==188){
System.out.println("边界值:"+integer);
}
a+=integer;
set.add(integer+"");
}
System.out.println("数据类型数:"+set.size());
}