KMP 문자열 일치 알고리즘

소개

KMP 알고리즘은 문자열 매칭 알고리즘으로 웹페이지 텍스트 검색, 텍스트에서 모든 패턴 발생 찾기, DNA 서열에서 특정 서열 검색 등 문자열 매칭이 널리 사용됩니다. 이 알고리즘은 Knuth, Morris 및 Pratt가 설계했으며 선형 시간에 문자열을 일치시킬 수 있는 알고리즘입니다. 다른 매칭 알고리즘으로는 무차별 대입 알고리즘, Rabin-Karp 알고리즘, 유한 오토마톤 알고리즘(정규식, 어휘 분석 등에 사용)이 있으며, 아래에서는 주로 KMP 알고리즘을 소개합니다.

복잡성

메인 스트링의 길이를 n으로, 패턴 스트링의 길이를 m으로 설정
매칭 시간 복잡도는 O(n)
보조 함수가 시간 복잡도를 계산 O(m)
보조 함수의 공간 복잡도는 O(m)
보조 함수는 패턴 문자열을 다음 배열에 기록하며, 문자열 일치 과정에서 접두사와 접미사 정보는 주 문자열의 역추적을 방지하여 O(n)의 일치 시간 복잡도를 달성합니다.

알고리즘에 대한 자세한 설명

1. 다음 배열


다음 배열은 패턴 문자열 P에 대한 next*[i] = k 설정입니다. 이는 패턴 문자열 P의 하위 문자열에서 아래 첨자 0부터 아래 첨자 i까지 동일한 접두사와 접미사가 있는 최대 문자 수 k를 나타냅니다. 여기서 k는 < =i-1.
다음 배열은 전체를 기준으로 다음* 배열을 기준으로 오른쪽으로 한 위치 이동하고 첫 번째 비트에 -1을 추가합니다. 이는 주로 사용 편의성을 위한 것입니다. KMP 알고리즘은 다음* 배열을 사용하여 수행할 수도 있습니다. .

예:

패턴 스트링 P
색인 0 1 2 4 5 6 7
다음* 0 0 1 2 4 0 저것
다음 -1 0 0 1 2 4 0

next*[0] = 0, 접미사와 접미사가 빈 문자열입니다.
next*[1] = 0, 접미사와 접미사가 다릅니다.
next*[2] = 1, 가장 긴 동일한 접미사와 접미사 "a"가 있습니다.
next* [3] = 2. 가장 긴 동일한 접미사 "ab"가
다음에 존재합니다*[4] = 3. 가장 긴 동일한 접미사 "aba"가
다음에 존재합니다*[5] = 4. 가장 긴 동일한 접미사 "abab"가
다음에 존재합니다*[6 ] = 0, 접미사도 접미사도 동일하지 않습니다.

다음* 배열 해결 과정

여기에 이미지 설명을 삽입하세요.

2. KMP 알고리즘

위의 매칭 과정
이미지 설명을 추가해주세요
에서 주 문자열은 다시 추적되지 않으며, 매칭이 실패할 경우 다음 데이터에 따라 패턴 문자열 매칭 위치가 조정됩니다. 주 문자열이 매칭에 실패한 위치는 여러 번 매칭될 수 있으나, 전체적인 복잡도는 동일하지 않으며 O(n)을 초과하지 않습니다.알고리즘 소개 부분에 KMP 알고리즘의 시간 복잡도에 대한 상각 분석이 나와 있습니다. 관심이 있는 경우 살펴보실 수 있습니다.

코드 구현

1. 다음 배열 코드를 푼다

void getNext(char * p, int * next) {
	next[0] = -1;
	int i = 0, j = -1;
	while (i < (int)strlen(p)) {
		if (j == -1 || p[i] == p[j]) {
			++i;
			++j;
			next[i] = j;
		} else {
			j = next[j];
		}
	}
}

2. KMP 매칭

int kmp(char * t, char * p)  {
	int i = 0; 
	int j = 0;
	while (i < (int)strlen(t) && j < (int)strlen(p)) {
		if (j == -1 || t[i] == p[j])  {
			i++;
       		j++;
		} else  {
       		j = next[j];
        }
    }
    if (j == strlen(p))
       return i - j;
    else 
       return -1;
}

추천

출처blog.csdn.net/ID314846818/article/details/127855809