해시 분할 및 정복

에서 재판 : 해시 분할과 정복 - 10 첫 번째 IP 통계의 가장 높은 수는 대용량 데이터를 표시

다음 코드는 다음과 같습니다

// 대규모 데이터 (10) IP 미리 출현의 가장 높은 수를 찾기 
// 알고리즘 사고, 분할 및 정복 
// IP 로그 파일 크기 10 GB의 약 억 IP, 64에 대한 MB의 메모리 제한 
//는 IP 로그 파일을 작은 해시 파일에 IP 모듈 (500), (500) 
// 동일한 IP는 같은 파일을 해시 
에, // 평균 작은 파일 20메가바이트 64MB의 
각 // 다시 각 IP에 대한 이진 트리 사용 작은 파일의 수를 계산 

// 이진 트리 탐색 및 IP의 발생의 최대 수 반환 
이, ^ 32 (2)되는 중복 IP를 생성 할 수 있도록 2 ^ (32) IP 생성해야하기 때문에 // IP를 
약을 // 64기가바이트 문서, 파일의 10기가바이트을 보장하기 위해 중복 IP를 생성 할 수 
100.100.100.100 - // 설정된 IP 섹션 0.0.0.0 
//에만 507 개의 파일을 열 수는 fopen () 

마스터 레코드 : 포스트 스크립트 @를 작은 파일 500 (점)로 구분 파일 후 
// 다른 컴퓨터 (규칙) 네트워크를 통해 전송이 작은 파일로 계산 될 수 
후 맵리 듀스 구글에서 작동 유사 메인 프로그램 // 결과, 즉 반환 

사용법 #include <stdio를. H> 
#INCLUDE <stdlib.h> 
#INCLUDE <time.h> 
#INCLUDE <io.h> // 통로 () 
사용법 #include <string.h>

CONST의 INT의 NUM은 = 1000000; // 천만 수동 NUM 수정 

부호 INT ITON (CHAR * IP)을 상기 서브 - 포인트 표기 // IP 어드레스 정수로 
공극 ntoi (NUM 부호 INT, CHAR * IP) 
의 INT fileexist (숯불 * 경로); // 파일을 결정하는 존재 
무효 fclose_all (파일 ** t을); // 가까운 모든 파일 
(숯불 * 경로) random_write int로; // 670,000,000 무작위로 생성 된 IP에 대한 10기가바이트 
hashfile에서 // 통계 가장 자주 IP 
무효 COUNT (* hashfile의 문자, 부호없는 INT * 데이터, NUM 부호 * INT), 
무효 정렬 (부호 INT * 최대, IP 부호 INT의 *, INT N-); // 정렬 
인라인 부호 INT 해시 (서명 INT의 IP ) // 해시 함수 
{창 (IP 500 %)} 

의 typedef 구조체 // 노드 노드 이진 
{ 
	부호 INT IP //는 IP 
	부호 INT N-, 발생의 횟수 // 
	노드 왼쪽 *; 
	노드 * 오른쪽; 
} 노드;

메인 INT (무효) 
{ 
	= NULL의 파일 *] 
	은 FILE *의 TMPFILE [505] 
	의 char * 경로 = "C : \\ ip_data.dat"; 
	숯 hashfile [50] 
	숯 BUF [20이다] 
	부호 추가, 데이터하는 int , N-] 
	부호 INT IP [10] 최대 [10]; // 기록 상위 10은 IP 
	부호 INT의 T1, T2, S, E; // 녹음 시간 
	INT I, J, 지금 렌, // IP의 개수 

	인 printf ( "S는 데이터를 생성 % \ N- \ N-"경로), 
	복귀 0 (! random_write (경로)) 경우 // 기록 파일은 임의로 생성 된 IP가 

	// == 0이 존재 접속 (), 폴더가 있는지를 판정한다 
	(0) == 0 액세스 ( "\\ hashfile C") IF 
		시스템 ( "RMDIR / S / QC : \\ hashfile"); 
	// 작업 빌드 디렉토리; 시스템 ( "\\ hashfile MKDIR C") 
	시스템 ( "ATTRIB + HC : \\ hashfile"); // 숨겨진 디렉토리 

	=하면 fopen에서 (경로, "RT ");// 개방형 IP 로그 파일
	(== NULL의) 복귀 경우에는 0 
	에 대한 (I = 0; I는 505 <; 내가 ++) [I]가 = NULL TMPFILE는; 

	// IP 505 작은 해시 파일 670 백만 것이다 
	에서 printf ( "\의 R은 S 해시 % \ N- \ N- "경로), 
	E = S = T1 = 클럭 (); 
	지금 = 0; 
	그동안합니다 (에 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-", 데이터), 
		렌 =의 나 strlen (버피); 
		// 파일은 IP에 기록됩니다 느린 디스크 읽기 및 쓰기 반복 
		에 fwrite (BUF 렌 ,. 1 TMPFILE [추가를]); 
		이제 ++; 
		E = 클럭 (); 
		IF (E - S>1000) 진행 상황을 계산하기 // 
		{
			printf와 (현 ( "0.2F %의 \의 T의 \ r을 진행 %% '*) / NUM 100.0) 
			S = E; 
		} 
	} 
	(에) FCLOSE; 
	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 // 때문에 
			// 너무 많은 요소가있는 경우, 당신은 삽입 정렬을 사용할 수 있습니다 스택 또는 찾을 생각 
			부호 INT 분 = 0xFFFFFFFF로, POS를, 
			대 (J = 0; J <10; J ++) 
			{ 
				IF (최대 [J] <I)
	}
// 디코딩 
		의 printf ( "% -20s % U \ N 'BUF 맥스 [I]);
		; fprintf와는 (BUF 맥스 [I], "% U % -20s \ N-"기록) 
	(- T1 "\ n ---- %의 0.3f 초 \ n을 사용하는 경우"(T2, 로그는 fprintf가 ) / 1000.0)를; 
	의 printf ( "\ n을 --- % 0.3f 초 사용 \ N- \ N-"(T2 - T1) / 1000.0) 
	FCLOSE (로그) 
	시스템 ( "RMDIR / S / QC : \\ hashfile"), 

	0을 반환 ; 
} 

공극 fclose_all (파일 ** T) 모든 파일을 닫고 // 
{ 
	I 값 int] 

	대 (I = 0; I <500; I는 ++) 
	{ 
		IF (T [I]) 
		{ 
			FCLOSE (T [I]) 
			T [ I = NULL; 
		} 
	} 
} 

랜덤 IP 생성 // 670,000,000, GB 10 
INT의 random_write (숯 * 경로) 
{ 
	은 FILE * OUT = NULL; 
	I는, J, B 값 int; 
	20 buf를 숯불 것은] 
	숯 *의 CUR ; 
	부호의 INT S, E;

	OUT = fopen은 (경로 "중량") 
	IF (OUT == NULL) 복귀 0] 
	부터 srand (시간 (NULL)); 
	E = S = 클럭 () 
	대 (I = 0; I는 NUM <; I는 ++) 
	{ 
		클럭 = E () 
		- IF (E S> 1,000) 진척 계산 // 
		{ 
			상기의 printf ( "\의 %%의 R & 0.2F %의 \의 T의 LT 진행"(I는 100.0 *) / NUM) 
			, S = E를 
		} 
		에 대해 (J = 0; J <20이고; J ++) [J] BUF = '\ 0'; 
		CUR = BUF; 
		위해 (., J <4; J = 0 J ++) 
		{ 
			// 점 표기법이 생성되어야 0-255 값 
			여기서 생성 // 값은 0-101이고 
			; B = RAND () 101 % 
			, (B 'D. % "CUR)의 sprintf 
			그동안 (* CUR ='\ 0 ') CUR ++; 
		} 
		* (CUR - . 1) = '\ N-'; 
		OUT ,. 1 BUF에 fwrite (BUF, CUR (숯 *)) 
	}
	FCLOSE (교체 아웃); // 닫기 기억 
	수익을 1;. 
부호 INT MAXN; // 입력 매개 변수 
노드 * max_node; // 출력 매개 변수 
무효 max_n (노드 * 트리) 가장 큰 트리 노드 N을 찾을 //
}

//二叉树的插入
무효 삽입 (노드 ** 나무, 부호없는 INT의 IP) 
{ 
	경우 ((* 트리) == NULL) 
	{ 
		// new_node 
		(* 나무) = (노드 *) malloc을 (를 sizeof (노드)); 
		(* 트리) -> IP = IP; 
		(* 트리) -> N = 1; 
		(* 트리) -> 왼쪽 = (* 트리) -> 우측 = NULL; 
	} 
	다른 경우 ((* 트리) -> IP == IP) 
	{ 
		(* 트리) -> N ++; 
		반환; 
	} 
	다른 경우 (IP <(* 트리) -> IP) //左子树
		삽입 (((* 트리) -> 왼쪽), IP); 
	다른 (((* 트리) -> 오른쪽), IP)를 삽입; //右子树
} 

{ 
	경우 (트리) 
	{ 
		경우 (트리 -> N> maxn) 
		{ 
			maxn = 트리 -> N; 
			max_node = 나무; 
		}
		max_n (트리 -> 좌측); 
		max_n (트리 -> 오른쪽); 
	} 
} 

공극 32 파괴 (* 노드 트리) //释放树
{ 
	경우 (트리) 
	{ 
		32 파괴 (트리 -> 좌측); 
		32 파괴 (트리 -> 오른쪽); 
		무료 (나무); 
	} 
} 

//统计hashfile中次数最多的IP 
공극 수 (숯의 hashfile *, * 부호 INT 데이터 부호의 INT * 않음) 
{ 
	= NULL의 파일 *; 
	노드 * 나무 = NULL; 
	서명되지 않은 INT의 IP; 

	=하면 fopen에서 (hashfile "RT"); 
	상태 (!는 fscanf (EOF "가 % d"에서, IP) =)
	max_n (나무); //结果在max_node의 
	* N = max_node-> N; 
	{
		(나무, IP)를 삽입; 
	} 
	(에) FCLOSE; 
	maxn = 0; 
	* 데이터 max_node- => IP; 
	(나무) 32 파괴; 
} 

//插入排序
공극 정렬 (부호 * 최대 INT, IP * 부호 INT, INT 않음) 
{ 
	I를 INT, J; 
	서명되지 않은 INT의 tmpm, tmpi; 

	대 (I = 1; i가 N <; 내가 ++) 
	{ 
		경우 (최대 [I-1] <맥스 [I]) 
		{ 
			tmpm 최대 = [I]; 
			tmpi IP = [I]; 
			에 대한 (j = 1; J> 0; j--) 
			{ 
				경우 (최대 [J-1] <tmpm) 
				{ 
					맥스 [J] = 최대 [J-1]; 
					IP [J] = IP [J-1]; 
				} 
				다른 휴식; 
			} 
			맥스 [J] = tmpm; 
			IP [J] = tmpi; 
		} 
	} 
} 

// 정수로 스트링의 IP 주소 
부호 INT ITON (* CHAR IP) 
{
	부호의 INT R = 0; 
	부호의 INT t; 
	int로 I, J; 

	에 대한 (j = 1 = 0; i가 <4; I ++) 
	{ 
		sscanf를 IP (+ J '가 % d ", t); 
		경우 (전 3 <) 
			동안 (IP [J ++]! = '.'); 
		R = R << 8; 
		R = t +; 
	} 
	R를 반환; 
} 

//将整型NUM转为字符型IP 
공극 ntoi (부호의 INT NUM, 숯 *의 IP) 
{ 
	부호의 INT B, F; 
	난 CUR int로; 

	F = 0x00FFFFFF; 
	CUR = 0; 
	대 (I = 3, I> = 0; 난 ...) 
	{ 
		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"); 
	경우 (FP) 
	{ 
		FCLOSE (FP); 
		1을 반환; 
	} 
	그렇지 않은 경우 0; 
}

  

추천

출처www.cnblogs.com/iupoint/p/11576879.html