我想从间隔 1,49 中抽取一个随机数,但我想添加一个数字作为例外(比方说 44 ),我不能使用 round(rand(1,49)) 。所以我决定49 个数字的数组 ( 1-49) ,
unset[$aray[44]]
并应用 array_rand
现在我想从区间 [$left,49] 中绘制一个数字,如何使用之前使用的相同数组来做到这一点?该数组现在缺少值 44。
函数 pick 接受一个数组作为参数,其中包含您已经选择的所有数字。 然后,它将在该数组中的开始和结束之间选择一个 IS NOT 的数字。 它将将此数字添加到该数组中并返回该数字。
function pick(&$picked, $start, $end) {
sort($picked);
if($start > $end - count($picked)) {
return false;
}
$pick = rand($start, $end - count($picked));
foreach($picked as $p) {
if($pick >= $p) {
$pick += 1;
} else {
break;
}
}
$picked[] = $pick;
return $pick;
}
此函数将有效地获取不在数组中的随机数并且永远不会无限递归!
如您所愿地使用它:
$array = array(44); // you have picked 44 for example
$num = pick($array, 1, 49); // get a random number between 1 and 49 that is not in $array
// $num will be a number between 1 and 49 that is not in $arrays
假设您得到一个 1 到 10 之间的数字。并且您选择了两个数字(例如 2 和 6)。 这将使用 rand 选择 1 到(10 减 2)之间的数字:
rand(1, 8)
。
然后它会遍历每个被选中的数字并检查该数字是否更大。
例如:
If rand(1, 8) returns 2.
It looks at 2 (it is >= then 2 so it increments and becomes 3)
It looks at 6 (it is not >= then 6 so it exits the loop)
The result is: 3
If rand(1, 8) returns 3
It looks at 2 (it is >= then 2 so it increments and becomes 4)
It looks at 6 (it is not >= then 6 so it exits the loop)
The result is 4
If rand(1, 8) returns 6
It looks at 2 (it is >= then 2 so it increments and becomes 7)
It looks at 6 (it is >= then 6 so it increments and becomes 8)
The result is: 8
If rand(1, 8) returns 8
It looks at 2 (it is >= then 2 so it increments and becomes 9)
It looks at 6 (it is >= then 6 so it increments and becomes 10)
The result is: 10
因此返回 1 到 10 之间的随机数,不会是 2 或 6。
我很早之前就实现了这个,将地雷随机放置在二维数组中(因为我想要随机地雷,但又想保证场上的地雷数量为一定数量)
为什么不直接检查你的例外情况:
function getRand($min, $max) {
$exceptions = array(44, 23);
do {
$rand = mt_rand($min, $max);
} while (in_array($rand, $exceptions));
return $rand;
}
请注意,如果您提供强制
mt_rand
返回异常字符的最小值和最大值,这可能会导致无限循环。 因此,如果你调用 getRand(44,44);
,虽然毫无意义,但会导致无限循环...(并且你可以通过函数中的一点逻辑来避免无限循环(检查函数中至少有一个非异常值)范围 $min
至 $max
)...
另一种选择是使用循环构建数组:
function getRand($min, $max) {
$actualMin = min($min, $max);
$actualMax = max($min, $max);
$values = array();
$exceptions = array(44, 23);
for ($i = $actualMin; $i <= $actualMax; $i++) {
if (in_array($i, $exceptions)) {
continue;
}
$values[] = $i;
}
return $values[array_rand($values)];
}
因为
unset()
和 array_rand()
都“使用”数组键,所以构建一个范围数组并翻转它是非常有意义的。 删除黑名单中的密钥,然后随机访问随机密钥。 演示
$array = array_flip(range(1, 49));
unset($array[44]);
echo array_rand($array);