Home >php教程 >php手册 >php生成多个不重复的随机数实例程序

php生成多个不重复的随机数实例程序

WBOY
WBOYOriginal
2016-05-25 16:50:291026browse

在php中生成随机数据直接使用mt_rand就可以实现了,如果要生成不重复随机数我们可以使用 unique_rand 函数了,实例代码如下:

<?php
//range 是将1到100 列成一个数组
$numbers = range(1, 100);
//shuffle 将数组顺序随即打乱
shuffle($numbers);
//array_slice 取该数组中的某一段
$no = 6;
$result = array_slice($numbers, 0, $no);
for ($i = 0; $i < $no; $i++) {
    echo $result[$i] . "<br>";
}
print_r($result);
//range 是将1到42 列成一个数组
$numbers = range(1, 42);
//shuffle 将数组顺序随即打乱
shuffle($numbers);
//array_slice 取该数组中的某一段
$result = array_slice($numbers, 0, 3);
print_r($result);
?>

实例代码二如下:

<?php
$numbers = range(1, 20);
srand((float)microtime() * 1000000);
shuffle($numbers);
while (list(, $number) = each($numbers)) {
    echo "$number ";
}
?>

实例代码三,用PHP,在1-20间随机产生5个不重复的值,代码如下:

<?php
function NoRand($begin = 0, $end = 20, $limit = 5) {
    $rand_array = range($begin, $end);
    shuffle($rand_array); //调用现成的数组随机排列函数
    return array_slice($rand_array, 0, $limit); //截取前$limit个
    
}
print_r(NoRand());
?>

或者不shuffle的话,代码如下:

<?php
$tmp = array();
while (count($tmp) < 5) {
    $tmp[] = mt_rand(1, 20);
    $tmp = array_unique($tmp);
}
print join(&#39;,&#39;, $tmp);
?>

上面都是纸上谈兵了,下面来真实的了,要求如下:

有25幅作品拿去投票,一次投票需要选16幅,单个作品一次投票只能选择一次,前面有个程序员捅了漏子,忘了把投票入库,有200个用户产生的投票序列为空,那么你会如何填补这个漏子?

当然向上级反映情况,但是我们这里讨论的是技术,就是需要生成1-25之间的16个不重复的随机数,去填补,具体怎么设计函数呢?将随机数存入数组,再在数组中去除重复的值,即可生成一定数量的不重复随机数,代码如下:

<?php
/*
 * array unique_rand( int $min, int $max, int $num )
 * 生成一定数量的不重复随机数
 * $min 和 $max: 指定随机数的范围
 * $num: 指定生成数量
*/
function unique_rand($min, $max, $num) {
    $count = 0;
    $return = array();
    while ($count < $num) {
        $return[] = mt_rand($min, $max);
        $return = array_flip(array_flip($return));
        $count = count($return);
    }
    shuffle($return);
    return $return;
}
$arr = unique_rand(1, 25, 16);
sort($arr);
$result = &#39;&#39;;
for ($i = 0; $i < count($arr); $i++) {
    $result.= $arr[$i] . &#39;,&#39;;
}
$result = substr($result, 0, -1);
echo $result;
?>

程序运行如下:1 2,3,4,6,7,8,9,10,11,12,13,16,20,21,22,24

补充几点说明:

•生成随机数时用了 mt_rand() 函数。这个函数生成随机数的平均速度要比 rand() 快四倍。

•去除数组中的重复值时用了"翻翻法",就是用 array_flip() 把数组的 key 和 value 交换两次。这种做法比用 array_unique() 快得多。

•返回数组前,先使用 shuffle() 为数组赋予新的键名,保证键名是 0-n 连续的数字。如果不进行此步骤,可能在删除重复值时造成键名不连续,给遍历带来麻烦。

再看一个实例:生成0-z这36个字符中的一个。每次调用 getOptions() 方法生成一个字符,它们的存储如下:array[0] = 0, array[1] = 1, ……, array[35] = z,代码如下:

Array (  
 [0] => 0  
 [1] => 1  
 [2] => 2  
 [3] => 3  
 [4] => 4  
 [5] => 5  
 [6] => 6  
 [7] => 7  
 [8] => 8  
 [9] => 9  
 [10] => a  
 [11] => b  
 [12] => c  
 [13] => d  
 [14] => e  
 [15] => f  
 [16] => g  
 [17] => h  
 [18] => i  
 [19] => j  
 [20] => k  
 [21] => l  
 [22] => m  
 [23] => n  
 [24] => o  
 [25] => p  
 [26] => q  
 [27] => r  
 [28] => s  
 [29] => t  
 [30] => u  
 [31] => v  
 [32] => w  
 [33] => x  
 [34] => y  
 [35] => z  
)

然后在0-35之间随机生成一个数作为索引,其实就是在上面数组中随机取出一个数,作为变量 $result 中的第一个字符,这个随机索引随后会被赋值成数组最后一个,它将不会参与下一轮的随机选取,代码如下:

<?php
// 生成0123456789abcdefghijklmnopqrstuvwxyz中的一个字符
function getOptions() {
    $options = array();
    $result = array();
    for ($i = 48; $i <= 57; $i++) {
        array_push($options, chr($i));
    }
    for ($i = 65; $i <= 90; $i++) {
        $j = 32;
        $small = $i + $j;
        array_push($options, chr($small));
    }
    return $options;
}
/*
$e = getOptions(); 
for($j=0; $j<150; $j++) 
{ 
 echo $e[$j]; 
} 
*/
$len = 10;
// 随机生成数组索引,从而实现随机数
for ($j = 0; $j < 100; $j++) {
    $result = "";
    $options = getOptions();
    $lastIndex = 35;
    while (strlen($result) < $len) {
        // 从0到35中随机取一个作为索引
        $index = rand(0, $lastIndex);
        // 将随机数赋给变量 $chr
        $chr = $options[$index];
        // 随机数作为 $result 的一部分
        $result.= $chr;
        $lastIndex = $lastIndex - 1;
        // 最后一个索引将不会参与下一次随机抽奖
        $options[$index] = $options[$lastIndex];
    }
    echo $result . "\n";
}
?>


教程链接:

随意转载~但请保留教程地址★

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn