背景:有个存有1000个问题的题库,用数组numHastack存,现要从中随机生成5道题。如果直接用随机数生成函数rand(),然后把生成的题号存到数组numGenerate中,会产生重复出现的问题。
参考我原来的博文:http://blog.csdn.net/wusuopubupt/article/details/8823145
1.最直接的解决办法:
每随机生成一个数,就拿到数组numGenerate中比较,如果存在,就重新rand,否则push到数组中,知道数组长度达到5.
这里关键就是借助in_array()函数判断num是否在array中。
<?php $numGenerate = array(); $max = 1000; for($i = 0;$i < 5;$i++){ $num = mt_rand(0,$max); while(in_array($num, $numGenerate)){ $num = mt_rand(0, $max); } $numGenerate[$i] = $num; } var_dump($numGenerate); ?>
2 用shuffle函数,把固定的数组打乱,然后,选择前5个即可
shuffle函数原理:http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
http://www.cnblogs.com/futuredo/archive/2012/10/23/2735686.html
我写的shuffle函数
<?php $times = 100; function my_shuffle() { global $times; $arr = range(0,9); //var_dump($arr); for($i = 0;$i <= $times;$i ++){ $num = mt_rand(0, 9); $temp = $arr[$num]; $arr[$num] = $arr[0]; $arr[0] = $temp; } return $arr; } var_dump(my_shuffle());
shuffle实现最终版:
<?php $numHastack = array(); $numGenerate = array(); $max = 1000;
//better method: range(0,1000) for($i = 0;$i <$max;$i++){ $numHastack[] = $i; } shuffle($numHastack); for($i =0;$i < 5;$i++){ $numGenerate[]= $numHastack[$i]; } var_dump($numGenerate); ?>
3.借助于hashtable(相当于每个数都对应一个flag),不到数组numGenerate中比较,而是用while循环检查hashtable[num] 的值是否为0(,没去过是默认为0,取过则设为1),如果不为0,则重新生成num,知道hashtable[num] == 0;
<?php $hashtable = array(); $numGenerate = array(); $max = 1000; for($i = 0;$i < 5;$i++){ $num = mt_rand(0,$max); while(@$hashtable[$num] > 0){ $num = mt_rand(0, $max); } $numGenerate[$i] = $num; $hashtable[$num] = 1; } var_dump($numGenerate); ?>
4.速度最快的算法(不做比较,只做交换)
<?php /** *generate 5 random numbers from total 1000 without duplicate * * */ $min = 0; $max = 1000; $numHastack = array(); $numGenerate = array(); for($i= 0;$i <= $max;$i++){ $numHastack[$i] = $i; } var_dump($numHastack); for($i = 0;$i < 5;$i++){ echo $max; $randIndex = mt_rand(0,$max); $numGenerate[$i] = $numHastack[$randIndex]; $numHastack[$randIndex] = $numHastack[$max]; $max--; } var_dump($numGenerate);
参考文献:http://www.cnblogs.com/eaglet/archive/2011/01/17/1937083.html
特别鸣谢:张亚杰同学http://www.cnblogs.com/buptpatriot