KMP 알고리즘 및 분석 템플릿

모든 데이터 구조, 알고리즘 및 응용 교육 과정 템플릿을 클릭하시기 바랍니다 : https://blog.csdn.net/weixin_44077863/article/details/101691360

KMP 알고리즘, 그것은 반드시 그 이름은, 알고리즘 폭력이 같은 이유가 의도하고 있는지에 대한 첫 번째 이야기

KMP는 너무 KMP이라는 알고리즘을 발명 한 이들의 세 세 누스, 모리스, 프랫이다. . . (DO는 놀라지 ..)

다음 문자열 패턴 매칭의 문제점을 해결하기 위해 사용된다 (고장 부분 문자열 찾는 것이다)

예를 들어, 그는 그런 말을 당신에게 마스터 문자열 S, T 문자열 모드, S 훨씬 문자열이 T, 마크의 시작 부분에 하위 문자열의 수를 포함하는 방법을 물어을 제공합니다

예를 들어, SO 4 서브 문자열 첨자는 0,1,2,3 = T = AA AAAAA 있습니다 S 개의

또 다른 예

1 문자열 5, 첨자

그런 다음 쓰기 A와 방법에 KMP 보증을 알게되지 않습니다 폭력 알고리즘에 대해 이야기

BF 알고리즘 (폭력 친구 ~입니다), 일반적인 패턴 매칭 알고리즘 인 스톰 (무력) 알고리즘을 호출

아니면 간단한 패턴 매칭 알고리즘을 NaiveStrMatching 호출 할 수 있습니다

사실은 매우 간단 더블 루프가 폭력 수단, S는 각 첨자 0 T 및 S 비교하기 시작, 0을 첨자

O의 시간 복잡도 (㎚)

그런 사람들이 T 매우 뒤로 이동이 필요하지 않습니다마다 실현하고 인덱스에서 시작 0 비트의 비교에 의해 비트는 완전히 불필요

예를 들어, 여전히 상기 ST

비교 결과의 첫 번째 라운드 :

다음 고용주가 다음 비교를 느낄 것, 보는 것은 더 가치가있다 :

P에서의 직접적인 비교도 표시.

순진한 알고리즘 폭력은 더 다음과 같다 :

그리고 제 2로 이동하는 경우, T는 0에서 비교가 시작됩니다

이 시간 K, M, P는 세 사람이 인간의 눈의 매칭 특성을 연구하기 시작했다

비교의 첫 번째 라운드는 T 매칭 프리픽스 문자열 : ABAB

이 문자열은 진정한 접두어 문자열을 가지고 : A, AB , ABA의를

진정한 후위 : B, AB , BAB-

이들은 발견 굵은 동일한 부

그래서이 법률, 우리는 첫 번째 라운드를 비교 차트를 살펴 보자

T T01 = T23를 들어, 다음 접미사 (23)을 보면, S23 = T23 = T01

T01는 S23로 이동 것이고, S4와 T2 직접 비교 될 수있다

그래서, KMP 알고리즘의 원리는 한 문장으로 요약한다 :

비교가 실패하면, 스트링이 성공적 프리픽스 A를 매치 된 참조 문자열 Y의 적절한 접미사을 실제는 동등의 X 접두사 문자열 존재

긴 가능한 경우 lenX (= lenY) 길이, 문자 및 다음 문자 위치 오류가 위치 Y, X 이동, X는 직접 비교는

위의 작업의주기가 일치 할 때까지 계속할 수 없습니다

사실,이 알고리즘은 완성 된 거리가 멀다

모든 이제 해당 접두사와 접미사를 찾을 매우 복잡하고 시간이됩니다

저장된 사전 아웃에 해당 그래서 첫 번째 위치

예 ABAB 번호는 (AB) B (3) (2)의 길이에 대응

우리는이 호출 특성 숫자 N을

아바바을 가지고

(교과서 N은, 사실, 좀 더 편안하게 다음 일반적인 쓰기를 할 수 있지만 보편적 인 헤더 파일을 포함하고 다음 모호한 오류가있을 것이다)

우리가 첫 라운드 경기에서 볼 때 그래서

난을 J = 4 =하면, 매치가 실패하고 상기 이동 J = N [J-1] 다음에 S [I] 및 T [J]를 비교

물론, 만약 J = 0 (첫 번째) 이미 없음 N [-1]이면, 직접 및 I와 같은 후퇴되지

그런 다음 시간에 따라 사전 N의 수는 너무 많은 폭력은 매우 느리게 될 경우

동적 프로그래밍의 개념으로 생각하는 이 일의 본질의 전처리가 KMP입니다

예를 들어, 4 비트 A, N [3] = 2, 후 직접 마스터 : T [4]와 모델 : T [2] 비교

T [4] == T [2] 다음, N [4] = N이 [3] + 1 = 3 일 후, 결정 발견 처음 다섯 (물론, 문자열이 5 이상없고, 그것의 끝)

가정 T [4] = T [2], 그리고 현재 참 다음 스트링의 접두사 문자열 해당 접두사 여부 판정 찾는 것이 결정 N [N [3] - 1]!, 즉, N [1]

그런 다음이 동등 할 때까지 반복

물론, 우리는 판정 후 N [4] = 0, 0이 아닌 것으로 가정

:( 템플릿 복잡도 O (N + m))은 다음과 같이 KMP 알고리즘은

char s[maxn],t[maxm]; //主串s,模式串t 
int n,m,N[maxm],cnt; //主串长n,模式串长m,特征数N,成功匹配个数cnt
vector<int> pos; //成功匹配位置所有下标(第一个字符)
void get_next(){
	m=strlen(t);
	for(int i=1;i<m;i++){
		int j=N[i-1];
		while(j&&t[i]!=t[j]) j=N[j-1];
		if(t[i]==t[j]) N[i]=j+1;
		else N[i]=0;
	}
}
void KMP(){
	n=strlen(s);
	int i=0,j=0;
	for(;i<n;i++){
		while(s[i]!=t[j]&&j) j=N[j-1];               
		if(s[i]==t[j]) j++;
		if(j==m) cnt++,pos.push_back(i-j+1);
	}
}

KMP 알고리즘 템플릿 질문 : https://cn.vjudge.net/problem/HihoCoder-1015

그것은 자신의 아래에 테스트 쓰기 KMP의 권리를 지불 할 수

发布了49 篇原创文章 · 获赞 0 · 访问量 1718

추천

출처blog.csdn.net/weixin_44077863/article/details/102172106