如何生成一个范围内的随机数但排除一些随机数,而不继续生成并检查生成的数字是否是我想要排除的数字之一?
原文由 AAaa 发布,翻译遵循 CC BY-SA 4.0 许可协议
如何生成一个范围内的随机数但排除一些随机数,而不继续生成并检查生成的数字是否是我想要排除的数字之一?
原文由 AAaa 发布,翻译遵循 CC BY-SA 4.0 许可协议
/**
* @param start start of range (inclusive)
* @param end end of range (exclusive)
* @param excludes numbers to exclude (= numbers you do not want)
* @return the random number within start-end but not one of excludes
*/
public static int nextIntInRangeButExclude(int start, int end, int... excludes){
int rangeLength = end - start - excludes.length;
int randomInt = RANDOM.nextInt(rangeLength) + start;
for(int i = 0; i < excludes.length; i++) {
if(excludes[i] > randomInt) {
return randomInt;
}
randomInt++;
}
return randomInt;
}
这个想法是将生成随机数的范围缩小到开始和结束之间的差值减去该范围内被排除的数字的计数。
所以你得到一个范围长度,它与可能的有效数字的数量相同。换句话说:您已经移除了范围内的所有漏洞。
生成随机数后,您必须将“空洞”放回范围内。这可以通过递增生成的数字来实现,只要排除的数字小于或等于生成的数字即可。较低的排除数字是生成数字之前范围内的“空洞”。对于该数字之前的每个孔,生成的数字都会向右移动。
原文由 Fabian Barney 发布,翻译遵循 CC BY-SA 3.0 许可协议
15 回答8.2k 阅读
8 回答6k 阅读
1 回答4.1k 阅读✓ 已解决
3 回答2.2k 阅读✓ 已解决
2 回答3.2k 阅读
2 回答3.9k 阅读
1 回答2.2k 阅读✓ 已解决
一种无需每次都重新生成随机数的可能解决方案是使用以下算法:
可以使用数组引用调用此方法,例如
或直接将号码插入电话:
它在
start
和end
(包括两者)之间生成一个随机数(int),并且不给你数组中包含的任何数字exclude
所有其他数字以相同的概率出现。请注意,必须满足以下约束条件:exclude
升序排列,所有数字都在提供的范围内,并且所有数字都互不相同。