将一个数M随机分为N份,并限制每份的大小

将一个数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());
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值