在一个范围内生成唯一的随机数 – PHP

我需要生成一个范围内的随机唯一数字? 怎么做 ?

我可以通过生成随机数

generator: $arr=array(); $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(我想要生成的数字)]

以随机顺序的数字范围的数组:

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

包装function:

 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 ) 
 $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的内存上限的风险。 评估范围和计数之间的比率并有条件地select发电机的混合动力将是两全其美的。

这个想法包括使用键,当一个值已经存在于数组键中时,数组的大小保持不变:

 function getDistinctRandomNumbers ($nb, $min, $max) { if ($max - $min + 1 < $nb) return false; // or throw an exception $res = array(); do { $res[mt_rand($min, $max)] = 1; } while (count($res) !== $nb); return array_keys($res); } 

临:这种方式避免了使用in_array ,并不会产生一个巨大的数组。 所以它速度快,保存了大量的内存。

缺点:当速率(范围/数量)减less时,速度也下降(但保持正确)。 对于相同的速率,相对速度随着范围的大小而增加。 (*)

(*)我明白这个事实,因为有更多的自由整数可供select(特别是第一步),但如果有人有描述这种行为的math公式,我感兴趣的是,不要犹豫。

结论:最好的“通用”函数似乎是这个函数和@Anne函数的混合,效率更高一些。 当需要一定的数量并达到一定的比率(范围/数量)时,此function应在两种方式之间切换。 所以testing的复杂性/时间知道这一点,必须考虑在内。

如果你想生成100个随机的数字,但每个数字只出现一次,一个好方法是生成一个有序的数组,然后洗牌。

像这样的东西:

 $arr = array(); for ($i=1;$i<=101;$i++) { $arr[] = $i; } shuffle($arr); print_r($arr); 

输出将如下所示:

 Array ( [0] => 16 [1] => 93 [2] => 46 [3] => 55 [4] => 18 [5] => 63 [6] => 19 [7] => 91 [8] => 99 [9] => 14 [10] => 45 [11] => 68 [12] => 61 [13] => 86 [14] => 64 [15] => 17 [16] => 27 [17] => 35 [18] => 87 [19] => 10 [20] => 95 [21] => 43 [22] => 51 [23] => 92 [24] => 22 [25] => 58 [26] => 71 [27] => 13 [28] => 66 [29] => 53 [30] => 49 [31] => 78 [32] => 69 [33] => 1 [34] => 42 [35] => 47 [36] => 26 [37] => 76 [38] => 70 [39] => 100 [40] => 57 [41] => 2 [42] => 23 [43] => 15 [44] => 96 [45] => 48 [46] => 29 [47] => 81 [48] => 4 [49] => 33 [50] => 79 [51] => 84 [52] => 80 [53] => 101 [54] => 88 [55] => 90 [56] => 56 [57] => 62 [58] => 65 [59] => 38 [60] => 67 [61] => 74 [62] => 37 [63] => 60 [64] => 21 [65] => 89 [66] => 3 [67] => 32 [68] => 25 [69] => 52 [70] => 50 [71] => 20 [72] => 12 [73] => 7 [74] => 54 [75] => 36 [76] => 28 [77] => 97 [78] => 94 [79] => 41 [80] => 72 [81] => 40 [82] => 83 [83] => 30 [84] => 34 [85] => 39 [86] => 6 [87] => 98 [88] => 8 [89] => 24 [90] => 5 [91] => 11 [92] => 73 [93] => 44 [94] => 85 [95] => 82 [96] => 75 [97] => 31 [98] => 77 [99] => 9 [100] => 59 ) 

如果你需要1到15之间的5个随机数,你应该这样做:

 var_dump(getRandomNumbers(1, 15, 5)); function getRandomNumbers($min, $max, $count) { if ($count > (($max - $min)+1)) { return false; } $values = range($min, $max); shuffle($values); return array_slice($values,0, $count); } 

如果您指定的计数值大于可能的数字范围,它将返回false。

你可以尝试下一个代码:

 function unique_randoms($min, $max, $count) { $arr = array(); while(count($arr) < $count){ $tmp =mt_rand($min,$max); if(!in_array($tmp, $arr)){ $arr[] = $tmp; } } return $arr; } 

获得一个随机数字。 它已经存储在数组中了吗? 如果没有,存储它。 如果是这样,那么去获得另一个随机数字并重复。

我想这大概是一个非问题,但我试图解决它。 我想我有一个相当不错的解决scheme。 以防其他人绊倒在这个问题上。

 function randomNums($gen, $trim, $low, $high) { $results_to_gen = $gen; $low_range = $low; $high_range = $high; $trim_results_to= $trim; $items = array(); $results = range( 1, $results_to_gen); $i = 1; foreach($results as $result) { $result = mt_rand( $low_range, $high_range); $items[] = $result; } $unique = array_unique( $items, SORT_NUMERIC); $countem = count( $unique); $unique_counted = $countem -$trim_results_to; $sum = array_slice($unique, $unique_counted); foreach ($sum as $key) { $output = $i++.' : '.$key.'<br>'; echo $output; } } 

randomNums(1100,1000,890000,899999);

这可能会解决你的问题:

 <?php print_r(array_rand(range(1,50), 5)); ?> 

这是我将如何做到这一点。

 $randnum1 = mt_rand(1,20); $nomatch = 0; while($nomatch == 0){ $randnum2 = mt_rand(1,20); if($randnum2 != $randnum1){ $nomatch = 1; } } $nomatch = 0; while($nomatch == 0){ $randnum3 = mt_rand(1,20); if(($randnum3 != $randnum1)and($randnum3 != $randnum2)){ $nomatch = 1; } } 

然后你可以回显结果来检查

 echo "Random numbers are " . $randnum1 . "," . $randnum2 . ", and " . $randnum3 . "\n"; 

“洗牌”方法有一个主要错误。 当数字很大的时候,洗牌30亿个指数会立即导致500错误。 这是真正的大数字的最佳解决scheme。

 function getRandomNumbers($min, $max, $total) { $temp_arr = array(); while(sizeof($temp_arr) < $total) $temp_arr[rand($min, $max)] = true; return $temp_arr; } 

假设我想从10亿到40亿获得10个唯一的随机数。

 $random_numbers = getRandomNumbers(1000000000,4000000000,10); 

PS:执行时间:0.027微秒

只需使用此function,并传递您想要生成的号码的数量

码:

 function randomFix($length) { $random= ""; srand((double)microtime()*1000000); $data = "AbcDE123IJKLMN67QRSTUVWXYZ"; $data .= "aBCdefghijklmn123opq45rs67tuv89wxyz"; $data .= "0FGH45OP89"; for($i = 0; $i < $length; $i++) { $random .= substr($data, (rand()%(strlen($data))), 1); } return $random;} 

生成唯一随机数的最好方法是

 <?php echo md5(uniqid(mt_rand(), true).microtime(true)); ?>