Rumah >pembangunan bahagian belakang >tutorial php >php排序1亿个QQ号码,该怎么处理

php排序1亿个QQ号码,该怎么处理

WBOY
WBOYasal
2016-06-13 11:59:27820semak imbas

php排序1亿个QQ号码
吃饱喝足了,还发贴了。
拆开分成几千份进行排序再合并。


首先先创建一个1亿个QQ号的txt。

<br /><?php<br /><br />// 创建一亿个QQ号的txt (大约需85~100秒)<br /><br />set_time_limit(0);<br />$fn = 'qq.txt';<br />$fp = fopen($fn, 'w');<br /><br />$st = microtime(true);<br /><br />$l = range(0,10000);<br />shuffle($l);<br />foreach ($l as $k=>$v)<br />{<br />	$arr = range($v*10000+10000,10000*($v+1)+9999);<br />	shuffle($arr);<br />	fputs($fp,implode("\n", $arr)."\n");<br />	unset($arr);<br />}<br /><br />echo  microtime(true)-$st;<br /><br />?><br />


 

稍等一两分钟1亿个随机QQ创建完成了。

QQ号码范围为>10000。文件大小大概有840MB。



下面就进行分类划分成几千份文件。

以QQ号码长度为文件夹,QQ号码前3位为文件名。

<br /><?php<br /><br />// 长度号码分类 (大约需360~400秒)<br /><br />set_time_limit(0);<br />$st = microtime(true);<br /><br />if(!is_dir('qq_no')) mkdir('qq_no');<br />$file = fopen('qq.txt', 'r'); <br /><br /><br />$i=0;<br />$end_s = '';<br />while(!feof($file))<br />{<br />	$g = 1042*1024;<br />	fseek($file,$g*$i);<br />	$s = fread($file, $g);<br /><br /> 	<br />	$end = strrpos($s, "\n");<br />	$arr_s = $end_s.substr($s, 0, $end);<br />	$end_s = substr($s, $end);<br /><br />	$arr = explode("\n", $arr_s);<br />	foreach ($arr as $k=>$v)<br />	{<br />		if($v!='')<br />		{<br />			$tag = "$v[0]$v[1]$v[2]";<br />			$text_arr[strlen($v)][$tag][] = $v;<br />		}<br />	}<br /><br />	foreach ($text_arr as $k=>$v)<br />	{<br />		$n_dir = 'qq_no/'.$k;<br />		if (!is_dir($n_dir)) mkdir($n_dir);<br />		foreach ($v as $tag=>$val)<br />		{<br />			$n_tf = fopen($n_dir.'/'.$tag.'.txt', 'a+');<br />			fputs($n_tf,implode("\n",$val)."\n");<br />		}<br />		<br />		<br />	}<br />	unset($text_arr);<br /><br />	++$i;<br /><br />}<br /><br />echo  microtime(true)-$st;<br /><br />?><br />




最后就要每个文件进行排序合并数据了。

<br /><?php<br /><br />// 排序完成拉 (800~920秒)<br /><br />set_time_limit(0);<br />$st = microtime(true);<br /><br />$qq_done = fopen('qq_done.txt', 'a+');<br /><br />$root = 'qq_no';<br />$dir_array = scandir($root);<br /><br />foreach ($dir_array as $key=>$val)<br />{<br />	if ($val != '.' && $val != '..')<br />		$dirs[$val] =  scandir($root.'/'.$val);<br />}<br /><br /><br />foreach ($dirs as $key=>$val)<br />{<br />	foreach ($val as $v)<br />	{<br />		if ($v != '.' && $v != '..')<br />		{<br />			$file = $root. '/' . $key . '/'. $v;<br />			$c = file_get_contents($file);<br />			$arr = explode("\n", $c);<br />			sort($arr);<br />			fputs($qq_done, implode("\n",$arr));<br />			unlink($file);<br />		}<br />	}<br />	rmdir($root. '/' . $key);<br />}<br />rmdir($root);<br /><br />echo  microtime(true)-$st;<br /><br />?><br />



总共大概花费了20多分钟。

虽然完成了,但方法很土鳖 0_0 ,坛里各位高手们改进改进啊。

------解决方案--------------------
来个C版本的
<br />#include <stdio.h><br /><br />#define BITSPERWORD 32<br />#define SHIFT 5<br />#define MASK 0x1F<br />#define N 100000000<br /><br />int a[1 + N/BITSPERWORD];<br /><br />void set(int i)<br />{<br />	a[i>>SHIFT] <br><font color='#FF8000'>------解决方案--------------------</font><br>= (1<<(i & MASK)); //i&MASK相当于1&(32-1),即1%32<br />}<br /><br />void clr(int i)<br />{<br />	a[i>>SHIFT] &= ~(1<<(i & MASK));<br />}<br /><br />int test(int i)<br />{<br />	return a[i>>SHIFT] & (1<<(i & MASK));<br />}<br /><br />int main()<br />{<br />	int i;<br />	//初始化<br />	for(i = 0; i < N; i++)<br />		clr(i);<br /><br />	//读取文件,置位<br />	while(scanf("%d", &i) != EOF)<br />		set(i);<br /><br />	for(i = 0; i < N; i++)<br />		if(test(i))<br />			printf("%d\n", i);<br /><br />	return 0;<br />}<br />

------解决方案--------------------

既然有现成的数据文件,就没有必要去构造插入串了
set_time_limit(0);<br />$sql =<<< SQL<br />CREATE TABLE IF NOT EXISTS qq1 (<br />  `qq` int(10) NOT NULL,<br />  KEY `qq` (`qq`)<br />) ENGINE=MyISAM DEFAULT CHARSET=utf8;<br />SQL;<br /><br />mysql_connect('localhost', 'root', '');<br />mysql_select_db('test');<br />mysql_query($sql);<br /><br />$filename = str_replace('\\', '/', realpath('qq.txt'));<br />$sql =<<< SQL<br />LOAD DATA INFILE '$filename' INTO TABLE qq1<br />SQL;<br /><br />check_speed(1);<br />mysql_query($sql) or print(mysql_error());;<br />check_speed();<br />
时间: 182,955,851 微秒
内存: 664

<br>set_time_limit(0);<br>mysql_connect('localhost', 'root', '');<br>mysql_select_db('test');<br><br>echo '升序<br>';<br>$filename = str_replace('\\', '/', dirname(__FILE__) . '/qq_1.txt');<div class="clear">
                 
              
              
        
            </div>
Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn