php排序1億個QQ號碼
吃飽喝足了,還發貼了。
拆開分成幾千份進行排序再合并。
首先先建立一個1億個QQ號的txt。
PHP code
$v){ $arr = range($v*10000+10000,10000*($v+1)+9999); shuffle($arr); fputs($fp,implode("\n", $arr)."\n"); unset($arr);}echo microtime(true)-$st;?>
稍等一兩分鐘1億個隨機QQ建立完成了。
QQ號碼範圍為>10000。檔案大小大概有840MB。
下面就進行分類劃分成幾千份檔案。
以QQ號碼長度為檔案夾,QQ號碼前3位為檔案名稱。
PHP code
$v) { if($v!='') { $tag = "$v[0]$v[1]$v[2]"; $text_arr[strlen($v)][$tag][] = $v; } } foreach ($text_arr as $k=>$v) { $n_dir = 'qq_no/'.$k; if (!is_dir($n_dir)) mkdir($n_dir); foreach ($v as $tag=>$val) { $n_tf = fopen($n_dir.'/'.$tag.'.txt', 'a+'); fputs($n_tf,implode("\n",$val)."\n"); } } unset($text_arr); ++$i;}echo microtime(true)-$st;?>
最後就要每個檔案進行排序合并資料了。
PHP code
$val){ if ($val != '.' && $val != '..') $dirs[$val] = scandir($root.'/'.$val);}foreach ($dirs as $key=>$val){ foreach ($val as $v) { if ($v != '.' && $v != '..') { $file = $root. '/' . $key . '/'. $v; $c = file_get_contents($file); $arr = explode("\n", $c); sort($arr); fputs($qq_done, implode("\n",$arr)); unlink($file); } } rmdir($root. '/' . $key);}rmdir($root);echo microtime(true)-$st;?>
總共大概花費了20多分鐘。
雖然完成了,但方法很土鱉 0_0 ,壇裡各位高手們改進改進啊。
------解決方案--------------------
來個C版本的
C/C++ code
#include #define BITSPERWORD 32#define SHIFT 5#define MASK 0x1F#define N 100000000int a[1 + N/BITSPERWORD];void set(int i){ a[i>>SHIFT] |= (1<<(i & MASK)); //i&MASK相當於1&(32-1),即1%32}void clr(int i){ a[i>>SHIFT] &= ~(1<<(i & MASK));}int test(int i){ return a[i>>SHIFT] & (1<<(i & MASK));}int main(){ int i; //初始化 for(i = 0; i < N; i++) clr(i); //讀取檔案,置位 while(scanf("%d", &i) != EOF) set(i); for(i = 0; i < N; i++) if(test(i)) printf("%d\n", i); return 0;}
------解決方案--------------------
既然有現成的資料檔案,就沒有必要去構造插入串了
PHP code
set_time_limit(0);$sql =<<< SQLCREATE TABLE IF NOT EXISTS qq1 ( `qq` int(10) NOT NULL, KEY `qq` (`qq`)) ENGINE=MyISAM DEFAULT CHARSET=utf8;SQL;mysql_connect('localhost', 'root', '');mysql_select_db('test');mysql_query($sql);$filename = str_replace('\\', '/', realpath('qq.txt'));$sql =<<< SQLLOAD DATA INFILE '$filename' INTO TABLE qq1SQL;check_speed(1);mysql_query($sql) or print(mysql_error());;check_speed();