より転載:ハッシュ分割統治-最初の10のIP統計データの最大数は、大量のデータを表示されます
次のようにコードは次のとおりです。
//は、大量のデータで10 IP発芽前の最大数を探す //アルゴリズムの考え方、分割統治 // IPログファイルのサイズを10 GB、およそ10億IP、64のためのMBのメモリ制限 // IPログファイルを小さなハッシュファイルにIPモジュロ500、500 //同じIPが同じファイルにハッシュさ で、//平均小ファイル20メガバイト64メガバイトを それぞれ//再び各IPのためのバイナリツリーを使用して、小さなファイルの数数える //バイナリツリートラバーサルをし、IPの出現回数の最大値を返します 2 ^ 32 IP生成する必要が2 ^ 32があるので、それが重複したIPを生成することができます確保するために、// IPを するのに約//を64ギガバイトの文書、ファイルの10ギガバイトを確保するために、重複したIP生成することができ 100.100.100.100 - //設定IPセクション0.0.0.0 //唯一の507個のまでのファイルを開くことができるのfopen() のマスタレコード:追伸@を小さなファイル500(ポイント)に分け、ファイルの後に //他のコンピュータ(ルール)ネットワークを介して送信されるこれらの小さなファイルに計算することができ 、その後、MapReduceのGoogleの作品に似て、メインプログラム//結果、すなわちに戻った の#include <stdioの。 H> の#include <stdlib.h>に含ま する#include <TIME.H> 書式#include <io.h> //アクセス() の#include <string.hの> CONST int型NUM = 1000000; //千万手動NUM変更 unsigned int型ITON(CHAR * IP)を、サブ点表記の// IPアドレス整数に 空隙ntoi(NUM unsigned int型、CHAR * IP); INT fileexist (char型*パス); //ファイルを決定するには、存在する のボイドFCLOSE_ALL(ファイル** t)を; // クローズすべてのファイルが (のchar *パス)random_write int型; // 6.7億ランダムに生成されたIP、10GB程度 hashfileで//統計ほとんどの場合、IP 無効COUNT(* hashfileはchar、unsigned int型*データ、NUM unsigned int型*); 無効ソート(unsigned int型* MAX、IP unsigned int型*、int型のn); //ソート インラインunsigned int型のハッシュ(unsigned int型のIP )//ハッシュ関数 {リターン(IP 500%);} のtypedef構造体//ノードノードバイナリ { unsigned int型IP; // IP unsigned int型N-、オカレンスの数// ノードが左*、 ノード*右; }ノード。 メインINT(ボイド) { = NULLのFILE *; FILEの*のTMPFILE [505]; チャー*パス= "C:\\ ip_data.dat"; チャーhashfile [50]; チャーBUF [20である]; 未署名の追加、データをint 、N-; unsigned int型IP [10]、最大[10]; //記録し、トップ10には、IP unsigned int型のT1、T2、S、E; //録画時間 INT I、J、今lenは、 ; // IPの数 printfは( "Sは、データを生成している%\ N- \ N-"、パス); 戻り値0(!random_write(パス))IF; //レコードファイルは、ランダムに生成されたIPが // == 0が存在してアクセス()、フォルダが存在する決定 IF(アクセス( "C:\\ hashfile"、0)== 0) システム( "rmdirを/ S / QC:\\ hashfile"); システム( "MKDIR C:\\ hashfile"); //作業ディレクトリを構築 システム( "ATTRIB + HC:\\ hashfile"); // 隠しディレクトリ =のfopenの中(パス、 "RT ");//オープンIPログファイル (== NULLで)IFリターン0; [i]をTMPFILE = NULL(;;私は505 <I ++がI = 0);のための // IPは505小さなハッシュファイルへ6.7億なり のprintf(「\ rがありますSハッシュ%\ N- \ N-」、パス); E = S = T1 =クロック(); 今= 0; 一方(IN関数fscanf( "%のS"、BUF)= EOF)! { データ= ITON(BUF ); // IPデジタル化された アドオン=ハッシュ(データ); //ハッシュアドレス、ファイルアドレス計算 ; sprintfの(hashfile、 "C :. hashfile \\ \\ hash_%U〜TMP"、追加) IF(TMPFILE [追加]を] == NULL)は 、TMPFILEは、[追加]は、関数fopen(hashfile、 "A")= はsprintf(bufは、 "%U \ N-"、データ); lenは=のSTRLEN(BUFを); //ファイルには、IPに書き込まれます、遅いディスクの読み取りおよび書き込み繰り返し fwriteの(BUF、LEN ,. 1、TMPFILE [追加を]); 今++; E =クロック(); IF(E - S>進捗状況を計算する1000)// { printf( "\ rを0.2F%の\ Tの%%進歩"、(今*)/ NUM 100.0); S = E; } } FCLOSE(IN); FCLOSE_ALL(TMPFILE); (パス)を削除; //すべての小さなファイルの統計は、コンピュータ処理の複数であってもよい、最高IP重複 マックス[I]は= 0;(; Iは、10 <I ++をI = 0)のための ための(I = 0; I <500; Iは++) { のsprintf (hashfile、 "C :. hashfile \\ \\ D〜TMP%のhash_"、I); IF(fileexist(hashfile)) { のprintf( "\ R&LT処理hash_%D〜TMP \ T" 、i)は、 //小さいファイルに最大のIP数カウント COUNT(hashfile、&データ、N-&)を、 最大の選択を記録するという考えを持つ唯一の10の要素は、ソート10 //ので //あまりにも多くの要素ならば、あなたは挿入ソートを使用することができますスタック又は見つけるために考え unsigned int型分= 0xFFFFFFFFを、POSと、 ため(J = 0; J <10; J ++) { IF(MAX [J] <I) { 最小=最大[J]、 POS = J; } } IF(N>分) { maxの[POS] = N-; IP [POS] =データ; } } } T2 =クロック(); ソート(最大、IP、 10); FILEは、* = NULLログ; // Cにある間:ip_result.txtレコード結果\ "\\ ip_result.txt C"、 "WT");ログ=のfopen( 関数fprintf(「、ログ\ Nアップ訪問第10 IP:N- \ N- \ "); fprintfの(ログ" N- "" IP ""訪問%-15s%S \ "); のprintf("最も訪問されたトップ10を\ n個の\ N- IP:\ N- \ N- "); のprintf(" %-15s%S \ N- "" IP "は、"訪問「); (I = 0; Iは、10 <; Iは++) { ntoi(IP [I ]、BUF)。デコード// printfの( "%-20s%U \ n"は、bufが、最大[i])と、 関数fprintf(ログ、 "%U%-20s \ N-"、BUF、最大[I]); } 関数fprintf(ログ"\ N --- N- \を使用して、%0.3F秒"、(T2 - T1)/ 1000.0); のprintf( "\ nの----%0.3F秒の\ nの\ nを使用する場合"(T2を - T1)/ 1000.0); fcloseを(ログ); システム( "rmdirを/ S / QC:\\ hashfile"); を返す0; } 無効FCLOSE_ALL(ファイル** T)は、すべてのファイルを閉じる// { 私はint型; (Iために= 0; Iは、500 <; Iは++) { T [I])(IF { FCLOSE(T [I]); T [I] = NULL; } } } ランダムに約10 GB、6.7億IPを生成// INT random_write (CHAR *パス) { FILE * OUT = NULLは、 IをINT、J、B、 チャーBUF [20である]; * CURをchar型、 unsigned int型S、E、 OUT =のfopen( "重量"パス); (OUT == NULL)戻り0 IF srand関数(時間(NULL)); E = S =クロック() のための(I = 0;私はNUMを<; Iは++) { ; E =クロック() S - IF(E > 1000)進捗//計算 { のprintf( "\の%%のR&0.2F%の\ TのLT進歩"、(I 100.0を*)/ NUM); S = E; } (J = 0; Jは<20であり; J ++) BUF [J] = '\ 0'; CUR = BUF; のため(J = 0; J <4; J ++) { //ドット表記の値は0〜255から生成されなければならない の0から101ここで生成された値@ B = RAND()%101; sprintfの(CUR、 "%D"、B)、 一方(!* CUR = '\ 0')CUR ++; } *(CUR - 1)= '\ N-'; fwriteの(BUF OUT、CUR(CHAR *)bufは、1); } } fcloseを(アウト); //閉じるために覚えて リターンを1; unsigned int型MAXN; //エントリのパラメータ ノード* max_node; //出力パラメータ 空max_n(ノード*ツリーは)//最大のツリーノードnを見つけます //二叉树的插入 、ボイド挿入(ノード**木、unsigned int型IP) { 場合((*木)== NULL) { // new_node (*ツリー)=(ノード*)はmalloc(はsizeof(ノード)); (*木) - > IP = IP; (*ツリー) - > N = 1。 (*ツリー) - >左=(*ツリー) - >右= NULL; } そうであれば((*ツリー) - > IP == IP) { (*ツリー) - > N ++。 返します。 } それ以外の場合(IP <(*木) - > IP)//左子树 挿入(&((*木) - >左)、腹腔内)。 他の(((*木)& - >右)、腹腔内)を挿入。//右子树 } { IF(木) { IF(TREE-> N> MAXN) { MAXN = TREE-> N。 max_node =木。 } max_n(TREE->左)。 max_n(TREE->右)。 } } ボイドDestoryは(ノード*ツリー)//释放树 { IF(木) { Destoryは(TREE->左)。 Destoryは(TREE->右)。 無料(木)。 } } //统计hashfile中次数最多的IP ボイド数(チャー*のhashfile、unsigned int型*データ、unsigned int型×n個) { = NULLのFILE *。 ノード*ツリー= NULL; unsigned int型のIP。 =用のfopen(hashfile、 "RT")で、 (fscanfは( "%d個"、&IP)!= EOF、中)間 { の挿入(&ツリー、腹腔内)。 } (中)FCLOSE。 MAXN = 0; max_n(木)。//结果在max_nodeの * N = max_node-> N; *データ= max_node-> IP; (木)Destoryは、 } //插入排序 無効ソート(unsigned int型* MAX、unsigned int型* IP、int型のn) { 私は、jはint型。 unsigned int型tmpm、TMPI。 (私は++; iがn <I = 1)のために { 場合(MAX [I-1] <maxの[I]) { tmpm =最大[I]。 TMPI = IP [i]は、 用(J = I、J> 0; j--) { IF(最大[J-1] <tmpm) { マックス[J] =最大[J-1]。 IP [J] = IP [J-1]。 } 他にブレーク。 } マックス[J] = tmpm。 IP [J] = TMPI。 } } } //整数に文字列のIPアドレス unsigned int型ITON(CHAR * IP) { unsigned int型のR = 0。 unsigned int型のトン。 int型I、J。 用(J = I = 0; iは<4; I ++) { のsscanf(IP + J、 "%のD"、&T)。 もし(私は3 <) しばらく(IP [J ++] =! ''); R = R << 8。 R + = T。 } Rを返します。 } //将整型NUM转为字符型IP 空隙ntoi(unsigned int型のNUM、チャー*のIP) { unsigned int型のB、F。 私はint型、CUR。 F = 0x00FFFFFF。 CUR = 0; 以下のための(I = 3; I> = 0; i--) { B = NUM >>(iは8 *)。 NUM = NUM&F。 F = F >> 8。 sprintf(IP + CUR、 "%U。"、B)。 しばらく(!IP [CUR] = '\ 0')CUR ++; \ 0' ; } } IP [CUR - 1] = '\ 0'; //判断文件存在 INT fileexist(チャー*パス) { FILEの*のFP = NULL; FP =のfopen(パス、 "RT")。 IF(FP) { FCLOSE(FP)。 1を返します。 } それ以外の戻り0; }