kmp 알고리즘 예제

예상되는 성능은 보장되지 않습니다. 문자열이 무작위가 아닌 경우 평가판 m을 확인하는 데 많은 문자 비교가 필요할 수 있습니다. 최악의 경우는 두 문자열이 마지막 문자를 제외한 모든 문자열에서 일치하는 경우입니다. 문자열 S[]가 모두 A인 1백만 자로 구성되고 W[]라는 단어가 최종 B 문자에서 종료되는 999A 문자라고 가정해 보세요. 간단한 문자열 일치 알고리즘은 이제 경기를 거부하고 평가판 위치를 진행하기 전에 각 평가판 위치에서 1000 자를 검사합니다. 간단한 문자열 검색 예제는 이제 약 1000 개의 문자 비교가 10 억 문자 비교를 위해 1 백만 개의 위치를 사용합니다. W[]의 길이가 n이면 최악의 경우 성능은 O(k로 n)입니다. 따라서 루프는 검색 알고리즘의 시간 복잡성이 O(n)임을 보여 주며, 대부분의 2n 시간동안 실행됩니다. Knuth-Morris-Pratt(KMP) 문자열 일치 알고리즘은 이차 시간에서 선형 시간까지 최악의 경우 동작이 크게 개선된 경우 를 (m + n) 작업에서 검색을 수행할 수 있습니다. KMP 일치 알고리즘은 패턴의 퇴화 속성(패턴에 두 번 이상 나타나는 동일한 하위 패턴을 갖는 패턴)을 사용하고 O(n)에 대한 최악의 경우 복잡성을 향상시킵니다. KMP 알고리즘의 기본 개념은 불일치를 감지할 때마다(일부 일치 후) 다음 창의 텍스트에 있는 일부 문자를 이미 알고 있다는 것입니다. 우리는 어쨌든 일치하는 것으로 알고있는 문자와 일치하지 않도록이 정보를 활용합니다. 우리가 이것을 이해하기 위해 아래 예제를 생각해 봅시다.

이 알고리즘은 1970년 도널드 크누스와 본 프랫에 의해, 그리고 제임스 에이치 모리스에 의해 독립적으로 고안되었다. 이것은 문자열 일치에 대한 최초의 선형 시간 알고리즘이었습니다. 세 사람은 1977년에 공동으로 출판했다. [1] 독립적으로, 1969년, Matiyasevich[2][3]는 문자열 패턴 일치 인식 문제를 연구하면서 2차원 튜링 머신으로 코딩된 유사한 알고리즘을 발견했습니다. m=10의 일치는 즉시 실패하므로 다음 알고리즘은 m = 11 및 i = 0을 시도합니다. 다음은 보다 일반적인 예입니다. 각 행은 외부 루프의 반복을 나타내며, 행의 각 문자는 비교 결과를 나타냅니다(비교가 같지 않은 경우 X). 텍스트 « 바나나노바노 »에서 패턴 « 나노 »를 찾고 있다고 가정해 보겠습니다. 알고리즘의 두 부분이 각각 O(k) 및 O(n)의 복잡성을 가지므로 전체 알고리즘의 복잡성은 O(n + k)입니다. 가장 간단한 알고리즘은 인덱스 m의 연속값, 검색 중인 문자열의 위치, 즉 S[m]에서 문자 일치를 찾는 것입니다. 인덱스 m이 문자열의 끝에 도달하면 일치하는 일치가 없으며 이 경우 검색이 « 실패 »라고 합니다. 각 위치에서 알고리즘은 먼저 검색 중인 단어의 첫 번째 문자의 같음, 즉 S[m] =를 확인합니다.

W[0]. 일치하는 단어가 발견되면 알고리즘은 단어 위치 인덱스i의 연속값을 확인하여 검색중인 단어의 다른 문자를 테스트합니다. 알고리즘은 검색 중인 단어에서 문자 W[i]를 검색하고 S[m+i] =? W[i]. 모든 연속 문자가 위치 m에서 W에서 일치하면 검색 문자열의 해당 위치에서 일치가 발견됩니다. 테이블 T의 이전 존재를 가정하면 Knuth-Morris-Pratt 알고리즘의 검색 부분에는 복잡성 O(n)가 있으며 n은 S의 길이이고 O는 큰 O 표기입니다. 함수를 입력하고 종료할 때 발생하는 고정 오버헤드를 제외하고 모든 계산은 while 루프에서 수행됩니다. 이 루프의 반복 횟수를 바인딩합니다. S[m]에서 시작된 일치항목이 S[m + i]와 W[i]를 비교하는 동안 실패할 경우, 다음 가능한 일치는 S[m + (i – T[i]]]에서 시작되어야 합니다.

특히 다음 가능한 일치는 m보다 높은 인덱스에서 발생해야 하므로 T[i] < i. W라는 단어의 모든 접두사에 대한 녹색 셀을 찾으면 불필요한 일치 항목을 몇 개 건너 뛰고 알고리즘의 효율성을 높일 수 있습니다.