ホームページ > バックエンド開発 > PHPチュートリアル > 1億のQQ番号をソートするためのPHPソリューション

1億のQQ番号をソートするためのPHPソリューション

WBOY
リリース: 2016-06-13 13:50:06
オリジナル
912 人が閲覧しました

PHP 1億QQ番号並べ替え
食べたり飲んだりした後、私も投稿しました。
それを何千もの部分に分割し、並べ替えて再度結合します。


まず、1 億個の QQ 番号を含む txt を作成します。

PHP コード
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
<?php

// 创建一亿个QQ号的txt (大约需85~100秒)

set_time_limit(0);
$fn = 'qq.txt';
$fp = fopen($fn, 'w');

$st = microtime(true);

$l = range(0,10000);
shuffle($l);
foreach ($l as $k=>$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 が作成されるまで 1 ~ 2 分待ちます。

QQ 番号の範囲は >10000 です。ファイルサイズは約840MBです。



以下は数千のファイルに分類されます。

QQ 番号の長さをフォルダー、QQ 番号の最初の 3 桁をファイル名として使用します。

PHP コード
<!--

Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
<?php

// 长度号码分类 (大约需360~400秒)

set_time_limit(0);
$st = microtime(true);

if(!is_dir('qq_no')) mkdir('qq_no');
$file = fopen('qq.txt', 'r'); 


$i=0;
$end_s = '';
while(!feof($file))
{
    $g = 1042*1024;
    fseek($file,$g*$i);
    $s = fread($file, $g);

     
    $end = strrpos($s, "\n");
    $arr_s = $end_s.substr($s, 0, $end);
    $end_s = substr($s, $end);

    $arr = explode("\n", $arr_s);
    foreach ($arr as $k=>$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 highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/

-->
<?php

// 排序完成拉 (800~920秒)

set_time_limit(0);
$st = microtime(true);

$qq_done = fopen('qq_done.txt', 'a+');

$root = 'qq_no';
$dir_array = scandir($root);

foreach ($dir_array as $key=>$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++ コード

#include <stdio.h>

#defineBITSPERWORD 32
#シフト 5 を定義
#マスク0x1Fを定義
#define N 100000000

int a[1 + N/ビットパーワード];

void set(int i)
{
    a[i>>SHIFT] |= (1>SHIFT] &= ~(1>SHIFT] & (1<font color="#e78608">------解決策------------------</font><br>
<br>既製のデータ ファイルがあるため、挿入文字列 <br><dl class="code">PHP コード<pre class="brush:php;toolbar:false"> を構築する必要はありません
set_time_limit(0);
$sql =<<<
存在しない場合はテーブルを作成 qq1 (
  `qq` int(10) NOT NULL、
  キー `qq` (`qq`)
) ENGINE=MyISAM デフォルトの文字セット=utf8;
SQL;

mysql_connect('localhost', 'root', '');
mysql_select_db('テスト');
mysql_query($sql);

$filename = str_replace('\', '/', realpath('qq.txt'));
$sql =<<<
データ INFILE '$filename' をテーブル qq1 にロードします
SQL;

チェック_スピード(1);
mysql_query($sql) または print(mysql_error());;
check_speed();
 <div class="clear"></div>
ログイン後にコピー
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート