如何从1~N中获取随机值但在PHP中排除几个特定值?

Gtk*_*ker 7 php random customization

rand(1,N)但不包括array(a,b,c,..),

是否已经有一个我不知道的内置函数,或者我必须自己实现它(如何?)?

UPDATE

合格的解决方案应该具有金性能,无论大小是否excluded array大.

pin*_*hic 16

没有内置函数,但你可以这样做:

function randWithout($from, $to, array $exceptions) {
    sort($exceptions); // lets us use break; in the foreach reliably
    $number = rand($from, $to - count($exceptions)); // or mt_rand()
    foreach ($exceptions as $exception) {
        if ($number >= $exception) {
            $number++; // make up for the gap
        } else /*if ($number < $exception)*/ {
            break;
        }
    }
    return $number;
}
Run Code Online (Sandbox Code Playgroud)

这是我的头脑,所以它可以使用抛光 - 但至少你不能最终陷入无限循环的情况,甚至假设.

:该功能中断,如果$exceptions 排气管你的范围-例如,呼叫randWithout(1, 2, array(1,2))randWithout(1, 2, array(0,1,2,3))将不会产生任何明智的(明显),但在这种情况下,返回的数值是外$from- $to范围,所以很容易赶上.

如果$exceptions保证已经排序,sort($exceptions);可以删除.

眼睛糖果:算法的一些简约可视化.


Pas*_*TIN 9

我不认为内置这样的功能; 你可能要自己编码.

要对此进行编码,您有两种解决方案:

  • 使用循环来调用rand()或mt_rand(),直到它返回正确的值
    • 这意味着在最坏的情况下多次调用rand()
    • 但如果N很大,那么这应该可以正常工作,并且你没有很多禁用值.
  • 构建一个仅包含合法值的数组
    • 并用它array_rand从中选择一个值
    • 如果N很小,它将正常工作

  • @Runner:这些都是直接和简单的算法来解决这个问题.没有太多(可能是None)其他方法来解决问题:如果遇到它们(上面的alg 1)或者从允许的值中选择(上面的alg 2),你可以消除排除的值.即使是聪明的实现也只是上面给出的主题的变体.你正在寻找的方法,`Magic()`,还没有用PHP编写. (3认同)

Mat*_*son 7

根据您的具体需求和原因,这种方法可能是一个有趣的选择.

$numbers = array_diff(range(1, N), array(a, b, c));
// Either (not a real answer, but could be useful, depending on your circumstances)
shuffle($numbers); // $numbers is now a randomly-sorted array containing all the numbers that interest you
// Or:
$x = $numbers[array_rand($numbers)]; // $x is now a random number selected from the set of numbers you're interested in
Run Code Online (Sandbox Code Playgroud)

因此,如果您不需要每次都生成一组潜在的数字,但是生成一次,然后从同一组中挑选一堆随机数,这可能是一个很好的方法.