码迷,mamicode.com
首页 > 编程语言 > 详细

浅谈php随机不重复数的两种算法

时间:2015-02-08 10:16:37      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

先引入别人的一个秒表计时类(counttime.class.php):

1.先看第一个例子(大数中取少数):

 1 <?
 2 /*
 3 @描述: Stopwatch这个类用户获取脚本执行时间
 4 @作者: Klesti Hoxha <klesti@gmail.com>
 5 */
 6 
 7 class Stopwatch {
 8 private $start;
 9 private $end;
10 private $markup_start = array();
11 private $markup_end = array();
12 
13 function __construct($markup=false) {
14 $this->start($markup);
15 }
16 
17 public function start($markup=false) {
18 if (!$markup) {
19 $this->start = $this->getmicrotime();
20 } else {
21 $this->markup_start[$markup] = $this->getmicrotime();
22 }
23 }
24 
25 public function stop($markup=false) {
26 if (!$markup) {
27 $this->end = $this->getmicrotime();
28 } else {
29 $this->markup_end[$markup] = $this->getmicrotime();
30 }
31 return $this->getDuration($markup);
32 }
33 
34 public function getDuration($markup=false) {
35     if (!$markup)
36      {
37         return number_format($this->end-$this->start,4);
38     } else {
39         return number_format($this->markup_end[$markup]-$this->markup_start[$markup],4);
40     }
41 }
42 
43 public function reset($markup) {
44 if (!$markup) {
45 $this->start = 0;
46 $this->end = 0;
47 $this->markup_start = array();
48 $this->markup_end = array();
49 } else {
50 $this->markup_start[$markup] = 0;
51 $this->markup_end[$markup] = 0;
52 }
53 }
54 
55 private function getmicrotime(){
56 list($usec, $sec) = explode(" ",microtime());
57 return ((float)$usec + (float)$sec);
58 }
59 
60 }
61 ?>

测试的两种方法如下:

 1 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 2 <?php
 3 require "counttime.class.php";//把类文件引用进来,根据你的实际情况来确定路径,这里是在同级目录
 4 $s = new Stopwatch();
 5 
 6 $s->start("section1");
 7 //range 是将1到100 列成一个数组
 8 $numbers = range (1,1000000);
 9 //shuffle 将数组顺序随即打乱
10 shuffle ($numbers);
11 //array_slice 取该数组中的某一段
12 $no=30;
13 $result = array_slice($numbers,0,$no);
14 for ($i=0;$i<$no;$i++){
15 echo $result[$i]."<br/>";
16 }
17 echo "第一个测验方法结束<br/><br/>";
18 $s->stop("section1");
19 
20 $s->start("section2");
21 function unique_rand($min, $max, $num)
22 {
23         $count = 0;
24         $return = array();
25         while ($count < $num) {
26             $return[] = mt_rand($min, $max);
27             $return = array_flip(array_flip($return));
28             $count = count($return);
29         }
30         shuffle($return);
31         return $return;
32 }
33 
34     $arr = unique_rand(1, 100000000000, 30);
35     $result = ‘‘;
36     for($i=0; $i < count($arr);$i++)
37     {
38         $result = $arr[$i];
39         echo $result."<br/>";
40     }
41     $s->stop("section2");
42 
43 
44 //输出时间
45 echo "Section 1 Duration: " . $s->getDuration("section1") . " seconds.<br/>";
46 echo "Section 2 Duration: " . $s->getDuration("section2") . " seconds.<br/>";
47 ?>

结果为:

 1 413537
 2 198587
 3 60611
 4 599544
 5 946241
 6 462853
 7 570943
 8 980260
 9 717416
10 969324
11 292403
12 614443
13 769469
14 151951
15 167883
16 308727
17 342706
18 955659
19 112311
20 329008
21 182668
22 330600
23 921966
24 993143
25 369227
26 747066
27 793185
28 347872
29 439016
30 428600
31 第一个测验方法结束
32 
33 649589727
34 450823813
35 324717181
36 44553762
37 375669657
38 37128612
39 25135327
40 468454185
41 73395357
42 753960006
43 214455797
44 5367614
45 1153263961
46 17803441
47 669057198
48 55366324
49 1117343950
50 203530485
51 1160930064
52 326487914
53 565471236
54 7068443
55 846955001
56 832037489
57 1067813034
58 219239595
59 1069795964
60 1049898846
61 926301266
62 197341539
63 Section 1 Duration: 0.5800 seconds.
64 Section 2 Duration: 0.0000 seconds.

 

结论:对于从大量数据中取少量数据,显然第二种比较快。

 

2.在来看看从大数中取大数:

 1 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 2 <?php
 3 require "counttime.class.php";//把类文件引用进来,根据你的实际情况来确定路径,这里是在同级目录
 4 $s = new Stopwatch();
 5 
 6 $s->start("section1");
 7 //range 是将1到100 列成一个数组
 8 $numbers = range (1,1000000);
 9 //shuffle 将数组顺序随即打乱
10 shuffle ($numbers);
11 //array_slice 取该数组中的某一段
12 $no=10000;
13 $result = array_slice($numbers,0,$no);
14 for ($i=0;$i<$no;$i++){
15 echo $result[$i]."<br/>";
16 }
17 echo "第一个测验方法结束<br/><br/>";
18 $s->stop("section1");
19 
20 $s->start("section2");
21 function unique_rand($min, $max, $num)
22 {
23         $count = 0;
24         $return = array();
25         while ($count < $num) {
26             $return[] = mt_rand($min, $max);
27             $return = array_flip(array_flip($return));
28             $count = count($return);
29         }
30         shuffle($return);
31         return $return;
32 }
33 
34     $arr = unique_rand(1, 1000000, 10000);
35     $result = ‘‘;
36     for($i=0; $i < count($arr);$i++)
37     {
38         $result = $arr[$i];
39         echo $result."<br/>";
40     }
41     $s->stop("section2");
42 
43 
44 //输出时间
45 echo "Section 1 Duration: " . $s->getDuration("section1") . " seconds.<br/>";
46 echo "Section 2 Duration: " . $s->getDuration("section2") . " seconds.<br/>";
47 ?>

输出结果为:

1 前面省略………………
2 Section 1 Duration: 0.6050 seconds.
3 Section 2 Duration: 17.4260 seconds.

结论:对于第一种方法输出一个数据的时间,跟大数的数字时间差不多。但是第二个时间显然耗费得要离谱。达到了17.5秒。

 

总结:

1.翻翻法对于选少量数据好用,大量数据就会比较吃力。

 

浅谈php随机不重复数的两种算法

标签:

原文地址:http://www.cnblogs.com/soongkun/p/4279720.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!