在一定范围内生成唯一随机数

php
2022-08-30 10:07:33

我需要在一个范围内生成随机的唯一数字,我该怎么做?我可以通过以下方式生成随机数

generator:
$arr = [];
$x = rand($min, $max);
$len = count($arr);
$flag = 0;
for($i = 0; $i < $len; $i++)
{
 if ($flag === 1)
   goto generator;
 if ($x === $arr[$i])
   $flag = 1;
}
$arr[$index] = $x;
$index++; 
goto generator;

我知道这个代码很糟糕,所以我需要一个更好的优化代码!帮助!

例如:如果我需要在1到15内生成3个数字,它们应该像5,9,1而不是3,1,2 [在1 - 3中(我想生成的数字)]


答案 1

具有随机顺序的数字范围的数组:

$numbers = range(1, 20);
shuffle($numbers);

包装函数:

function UniqueRandomNumbersWithinRange($min, $max, $quantity) {
    $numbers = range($min, $max);
    shuffle($numbers);
    return array_slice($numbers, 0, $quantity);
}

例:

<?php
print_r( UniqueRandomNumbersWithinRange(0,25,5) );
?>

结果:

 Array
(
    [0] => 14
    [1] => 16
    [2] => 17
    [3] => 20
    [4] => 1
)

答案 2
$len = 10;   // total number of numbers
$min = 100;  // minimum
$max = 999;  // maximum
$range = []; // initialize array
foreach (range(0, $len - 1) as $i) {
    while(in_array($num = mt_rand($min, $max), $range));
    $range[] = $num;
}
print_r($range);

我很想看看被接受的答案如何与我的答案相媲美。值得注意的是,两者的混合可能是有利的;实际上是一个函数,它根据某些值有条件地使用一个或另一个:

# The accepted answer
function randRange1($min, $max, $count)
{
    $numbers = range($min, $max);
    shuffle($numbers);
    return array_slice($numbers, 0, $count);
}

# My answer
function randRange2($min, $max, $count)
{
    $range = array();
    while ($i++ < $count) {
        while(in_array($num = mt_rand($min, $max), $range));
        $range[] = $num;
    }
    return $range;
}

echo 'randRange1: small range, high count' . PHP_EOL;
$time = microtime(true);
randRange1(0, 9999, 5000);
echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;

echo 'randRange2: small range, high count' . PHP_EOL;
$time = microtime(true);
randRange2(0, 9999, 5000);
echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;

echo 'randRange1: high range, small count' . PHP_EOL;
$time = microtime(true);
randRange1(0, 999999, 6);
echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;

echo 'randRange2: high range, small count' . PHP_EOL;
$time = microtime(true);
randRange2(0, 999999, 6);
echo (microtime(true) - $time) . PHP_EOL . PHP_EOL;

结果:

randRange1: small range, high count
0.019910097122192

randRange2: small range, high count
1.5043621063232

randRange1: high range, small count
2.4722430706024

randRange2: high range, small count
0.0001051425933837

如果您使用较小的范围和较高的返回值计数,则接受的答案肯定是最佳的;但是,正如我所期望的那样,使用可接受的答案,较大的范围和较小的计数将花费更长的时间,因为它必须在范围内存储每个可能的值。您甚至冒着吹走PHP内存上限的风险。评估范围和计数之间的比率并有条件地选择发电机的混合体将是两全其美的。


推荐