도구스개발

KMP 실패함수·문자열 검색 계산기

패턴의 실패함수(부분일치 테이블)를 만들고, 본문에서 찾을 때 어디서 어긋나 몇 칸 밀리는지 단계별로 보여 줍니다. 브루트포스와 문자 비교 횟수를 나란히 놓아 이득을 수치로 확인할 수 있습니다.

400자까지 다룹니다.

60자까지 다룹니다.

찾은 자리

10번째

인덱스 10 (0부터 셉니다)

KMP 문자 비교 횟수23회
브루트포스 문자 비교 횟수29회
아낀 비교6회 (20.7%)
패턴을 놓아 본 자리8곳

① 실패함수 π — 접두사이면서 접미사인 가장 긴 길이

i글자P[0..i]π[i]그 길이의 접두사=접미사
0AA0
1BAB0
2AABA1A
3BABAB2AB
4CABABC0
5AABABCA1A
6BABABCAB2AB
7AABABCABA3ABA
8BABABCABAB4ABAB

π[i]는 P[0..i]의 «진접두사이면서 동시에 접미사인 가장 긴 문자열»의 길이입니다. 자기 자신은 빼고 세므로 π[0]은 언제나 0입니다. 이 표를 만드는 데 문자 비교 9회가 들었습니다.

② 검색 과정 — 어디서 어긋나 몇 칸 밀렸나

패턴 위치맞춘 길이결과비교밀린 칸
04P[4]에서 어긋남52
22P[2]에서 어긋남12
40P[0]에서 어긋남11
53P[3]에서 어긋남42
71P[1]에서 어긋남11
80P[0]에서 어긋남11
90P[0]에서 어긋남11
109전부 일치95

③ 같은 과정을 그림으로

ABABDABACDABABCABAB
ABABCABAB
  ABABCABAB
    ABABCABAB
     ABABCABAB
       ABABCABAB
        ABABCABAB
         ABABCABAB
          ABABCABAB

진하게 칠한 앞부분이 맞은 구간, 붉은 뒷부분이 어긋난 자리와 그 뒤로 보지 않은 구간입니다. 본문 포인터는 한 번도 왼쪽으로 돌아가지 않습니다 — 되돌리지 않는 것이 KMP의 전부입니다.

사용 방법

  1. 1찾을 대상이 되는 본문과 찾을 패턴을 각각 넣습니다. 예제 버튼으로 교과서 자료를 바로 넣을 수도 있습니다.
  2. 2실패함수 표에서 π[i]가 어떤 접두사=접미사의 길이인지 오른쪽 칸으로 확인합니다.
  3. 3검색 과정 표에서 패턴이 놓인 자리마다 몇 글자를 맞췄고 어디서 어긋나 몇 칸 밀렸는지 봅니다.
  4. 4KMP 비교 횟수와 브루트포스 비교 횟수를 견주어 이 자료에서 얼마나 이득인지 확인합니다.

자주 묻는 질문

패턴의 각 자리까지에서 「진접두사이면서 동시에 접미사인 가장 긴 문자열의 길이」입니다. 예를 들어 ABABCABAB의 마지막 자리 값은 4인데, 앞 4자 ABAB와 뒤 4자 ABAB가 같기 때문입니다. 어긋났을 때 이 길이만큼은 이미 맞은 것으로 치고 건너뛸 수 있어 본문을 되돌려 읽지 않아도 됩니다. 부분일치 테이블, LPS 배열이라고도 부릅니다.

진접두사는 자기 자신을 뺀 접두사이기 때문입니다. 글자가 하나뿐이면 자기 자신 말고는 접두사가 없으므로 길이가 0이 됩니다. 이 규칙을 빼먹고 π[0]을 1로 두면 표 전체가 한 칸씩 어긋나 검색이 무한히 돌 수 있습니다.

규약이 달라서일 뿐 둘 다 맞습니다. 이 계산기는 0부터 세는 배열에 「길이」를 담는 흔한 규약을 씁니다. 원논문에 가까운 서술은 f[i] = π[i] − 1로 두어 −1이 등장하고, 1부터 세는 교재는 값이 한 칸씩 밀려 보입니다. 표에 −1이 있으면 다른 규약이며, 담긴 정보는 같습니다.

아닙니다. 최악의 경우가 O(n+m)으로 보장되는 것이지 언제나 비교를 덜 하는 것은 아닙니다. 본문에 패턴의 첫 글자가 드물면 브루트포스도 본문을 거의 한 번만 훑어 비교 횟수가 비슷합니다. 차이는 「앞부분이 길게 맞다가 뒤에서 어긋나는」 자료에서 벌어지며, AAAA…AAB에서 AAAAB를 찾는 경우가 대표적입니다.

찾습니다. AAAAA에서 AA를 찾으면 0, 1, 2, 3 네 곳이 모두 나옵니다. 패턴 전체가 맞으면 j를 0으로 되돌리지 않고 π[m−1]로 낮추기 때문이며, 그래서 앞선 일치와 겹치는 자리도 놓치지 않습니다.

전송되지 않습니다. 모든 계산은 브라우저 안에서 이뤄지고, 입력값은 이 기기에만 남습니다.

알아두면 좋은 점

  • 검증은 CLRS「Introduction to Algorithms」의 예제(본문 ABABDABACDABABCABAB, 패턴 ABABCABAB → 인덱스 10)와 AABAACAABAA의 실패함수 0 1 0 1 2 0 1 2 3 4 5로 했습니다. 무작위 자료 400벌에서 브루트포스와 찾은 자리가 완전히 같은지도 대조했습니다.
  • 비교 횟수는 「본문 한 글자 대 패턴 한 글자」를 1회로 셉니다. 어긋나 j를 낮춘 뒤 같은 본문 자리를 다시 견주는 것도 각각 셉니다. 실패함수를 만드는 데 든 비교는 검색 비교와 따로 표시합니다.
  • 글자는 유니코드 코드포인트가 아니라 자바스크립트 문자열의 코드 단위로 셉니다. 이모지처럼 두 단위를 차지하는 문자가 섞이면 인덱스가 눈에 보이는 글자 수와 어긋날 수 있습니다.
  • 본문 400자·패턴 60자까지만 다룹니다. 과정을 보이는 것이 목적이라 그보다 길면 표가 읽히지 않습니다.
  • 실제 검색 라이브러리는 KMP보다 보이어-무어나 그 변형을 더 많이 씁니다. 패턴 뒤에서부터 견주어 한 번에 여러 칸을 건너뛸 수 있기 때문이며, KMP는 최악의 경우를 보장하는 쪽에 값어치가 있습니다.

함께 보면 좋은 도구

마지막 검증: 2026년 9월 1일 · 결과는 참고용 추정치입니다.