How*_*ard 44
每次随机无需再生的一种可能解决方案是使用以下算法:
public int getRandomWithExclusion(Random rnd, int start, int end, int... exclude) {
int random = start + rnd.nextInt(end - start + 1 - exclude.length);
for (int ex : exclude) {
if (random < ex) {
break;
}
random++;
}
return random;
}
Run Code Online (Sandbox Code Playgroud)
可以使用数组引用调用此方法,例如
int[] ex = { 2, 5, 6 };
val = getRandomWithExclusion(rnd, 1, 10, ex)
Run Code Online (Sandbox Code Playgroud)
或直接将号码插入电话:
val = getRandomWithExclusion(rnd, 1, 10, 2, 5, 6)
Run Code Online (Sandbox Code Playgroud)
它在(start和)之间生成一个随机数(int),并且end不会为您提供数组中包含的任何数字exclude.所有其他数字的概率相等.请注意,以下约束必须保持:exclude按升序排序,所有数字都在提供的范围内,并且所有数字都是相互不同的.
Fab*_*ney 16
/**
* @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;
}
Run Code Online (Sandbox Code Playgroud)
该想法是将产生随机数的范围减小到开始和结束之间的差减去该范围内被排除的数字的数量.
因此,您获得的范围长度与可能的有效数字的数量相同.换句话说:你已经从范围中移除了所有洞.
生成随机数后,您需要将"孔"放回范围内.只要排除的数字低于或等于生成的数字,就可以通过递增生成的数字来实现这一点.较低的排除数是在生成的数字之前的范围内的"空洞".并且在该数字之前为每个孔移动生成的数字.