// education

17. 문자열 검색 알고리즘 - KMP(Knuth-Morris-Pratt $O(N+M)$)와 라빈-카프(Rabin-Karp)

긴 본문 텍스트 내에서 특정 패턴 문자열의 위치를 $O(N+M)$ 선형 시간에 빠르게 찾아내는 KMP 알고리즘과 **라빈-카프(Rabin-Karp)**를 배웁니다.


4. 실전 파이썬(Python 3) 알고리즘 구현 코드 및 라인별 주석 해설

본 레슨의 핵심 연산 매커니즘을 파이썬 3 환경에서 가장 효율적이고 직관적으로 구현한 실전 소스 코드입니다. 모든 주요 라인마다 상세한 한글 주석이 기재되어 있어 코드의 흐름을 쉽고 명확하게 이해할 수 있습니다.

def build_lps(pattern: str) -> list:
    """KMP 실패 함수 (Longest Proper Prefix which is also Suffix 배열) 생성"""
    lps = [0] * len(pattern)
    length = 0  # 이전 일치 접두사 길이
    i = 1
    while i < len(pattern):
        if pattern[i] == pattern[length]:
            length += 1
            lps[i] = length
            i += 1
        else:
            if length != 0:
                length = lps[length - 1]  # LPS 테이블을 통해 건너뜀
            else:
                lps[i] = 0
                i += 1
    return lps

def kmp_search(text: str, pattern: str) -> list:
    """KMP 패턴 매칭 O(N + M)"""
    lps = build_lps(pattern)
    matches = []
    i = j = 0  # i: text 인덱스, j: pattern 인덱스
    
    while i < len(text):
        if pattern[j] == text[i]:
            i += 1
            j += 1
        if j == len(pattern):
            matches.append(i - j)  # 일치 패턴 매칭 위치 발견
            j = lps[j - 1]         # 점프!
        elif i < len(text) and pattern[j] != text[i]:
            if j != 0:
                j = lps[j - 1]     # 불일치 시 LPS 테이블로 인덱스 점프
            else:
                i += 1
    return matches

if __name__ == "__main__":
    txt = "ABABDABACDABABCABAB"
    pat = "ABABCABAB"
    print("KMP 패턴 일치 인덱스 목록:", kmp_search(txt, pat))

파이썬 소스 코드 핵심 포인트 해설

  1. build_lps(): 접두사와 접미사의 일치 길이를 저장하는 실패 함수(LPS)를 $O(M)$ 타임에 생성합니다.

5. 알고리즘 설계 및 최적화 실무 지침 (Best Practices & Complexity Audit)

17. 문자열 검색 알고리즘 - KMP(Knuth-Morris-Pratt $O(N+M)$)와 라빈-카프(Rabin-Karp) 레슨에서 익힌 핵심 알고리즘 메커니즘을 코딩 테스트 및 대규모 웹/서버 엔지니어링 환경에 도입할 때 반드시 체크해야 하는 튜닝 가이드입니다.

1) 공간/시간 복잡도 한계 및 메모리 사용 제어

2) 예외 케이스(Edge Cases) 및 코딩 테스트 체크리스트

  1. 입력 경계값 검증: $N=1$ 이거나 $N=0$ 인 극단적 최소 입력, 혹은 모든 요소의 값이 동일한 경우(Corner Case)에 대한 예외 처리를 누락하지 않습니다.
  2. 무한 루프 및 사이클 감지: 그래프/트리 탐색 시 방문 처리 배열(visited[])의 업데이트 위치를 정확히 지정하여 중복 큐 삽입으로 인한 메모리 초과를 예방합니다.

6. 핵심 요약 및 실무 FAQ (Summary & Q&A)

Q1. 파이썬 코드 주석에서 강조된 성능 핵심은 무엇인가요?

Q2. 실무 개발에서 본 파이썬 알고리즘 패턴은 어디에 활용되나요?

← 이전16. 위상 정렬(Topological Sort)과 방향 비순환 그래프(DAG) - 진입 차수와 Kahn 알고리즘 다음 →18. 트리 심화 - 최소 공통 조상(LCA: Lowest Common Ancestor) 및 희소 배열(Sparse Table)