首頁  >  文章  >  後端開發  >  php排序1亿个QQ号码,该如何解决

php排序1亿个QQ号码,该如何解决

WBOY
WBOY原創
2016-06-13 12:58:01882瀏覽

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) <div class="clear">
                 
              
              
        
            </div></stdio.h>
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn