ONE QUESTION AT A TIME.

천천히 생각하고, 분명하게.

TODAY’S QUESTION102 / 1500

텍스트가 소켓으로 한 글자씩 들어올 때 KMP 상태만으로 패턴 매치를 계속 보고하려면 무엇을 보관하나요?

잠깐, 답변을 보기 전에
먼저 내 말로 설명해 볼까요?

답변과 점검 포인트 펼치기답변 접기
01

구두 답변

정의를 외우기보다, 원리와 조건을 연결해 설명해 보세요.

고정 패턴을 스트리밍으로 찾으려면 패턴 자체, 미리 계산한 π 배열, 현재 일치 길이 j, 그리고 외부에 보고할 누적 텍스트 위치를 보관합니다. 전체 텍스트나 현재 청크를 이어 붙여 저장할 필요는 없습니다. 새 문자가 오면 j>0이고 pattern[j]가 다를 때 j=π[j-1]를 반복하고, 일치하면 j++합니다. j는 청크가 끝나도 그대로 다음 청크로 넘어갑니다.

패턴 길이가 4이고 첫 청크 끝 상태가 j=3이라고 하겠습니다. 다음 청크의 첫 문자가 네 번째 패턴 문자와 같으면 상태 4가 되고 그 위치에서 매치를 보고합니다. 보고한 뒤 j=π[3]으로 바꿔야 겹치는 다음 매치가 이어집니다. 이를 0으로 만들면 경계 바로 앞에서 시작한 겹침을 놓칩니다. 텍스트 위치는 문자를 소비할 때마다 증가시키며, 바이트 스트림이면 바이트 오프셋, 코드 포인트 스트림이면 코드 포인트 오프셋이라는 단위를 명시해야 합니다.

청크마다 상태를 초기화하는 구현은 청크 내부 검색만 하므로 패턴이 두 청크에 걸친 출현을 잃습니다. 빈 패턴을 허용할지와 연결 종료 시 미완성 상태를 어떻게 처리할지는 KMP 공식이 아니라 스트림 API의 계약으로 정합니다.

청크 계약에서는 소비와 상태 갱신의 순서도 중요합니다. 문자 하나를 읽은 뒤 현재 누적 위치를 먼저 정하고, fallback과 일치 검사를 끝낸 다음 매치 이벤트에 그 위치를 넣습니다. 매치 이벤트를 비동기로 큐에 넣더라도 다음 문자를 처리하기 전에 j를 fallback해야 같은 처리 루프가 overlap을 정확히 이어 갑니다. 이벤트 전송이 실패했다고 검색 상태까지 되돌리면 입력 소비 위치와 결과 재시도 정책이 섞이므로, 최소한 검색기 내부 상태와 이벤트 전달 상태를 분리해야 합니다.

패턴을 바꾸는 경우에는 기존 j를 새 패턴에 재사용할 수 없습니다. j가 뜻하는 border와 π 배열의 인덱스가 새 패턴에 대해 무효이기 때문입니다. 새 패턴의 π를 준비한 뒤 상태를 0에서 시작하거나, 패턴 교체 시점의 텍스트를 새 패턴으로 다시 정의하는 계약이 필요합니다. 이 구분이 없으면 청크 경계 버그처럼 보이지만 실제로는 패턴 세대가 섞인 결과가 됩니다.

02

득점 포인트

이해가 드러나는 지점을 확인해 보세요.

  • 청크 사이에 j와 누적 위치를 유지한다.
  • 완전 일치 뒤 π[m-1]로 fallback해 overlap을 허용한다.
  • 문자 단위와 반환 오프셋 단위를 일치시킨다.
03

감점 포인트

놓치기 쉬운 조건과 오해를 짚어 보세요.

  • 청크마다 j=0으로 재시작해 경계 매치를 놓친다.
  • 매치 뒤 상태를 항상 0으로 만들어 중첩 출현을 누락한다.
04

더 파고들 거리

하나 더 질문하며 이해의 범위를 넓혀 보세요.

  • 백프레셔로 문자가 지연될 때 검색 상태와 소비 위치를 어떻게 원자적으로 갱신할까요?
  • 기존 j와 π는 이전 패턴의 border 의미만 가지므로 새 패턴 세대에서는 상태 0부터 다시 정의해야 합니다.

득점·감점 포인트는 학습용 자기 점검 기준이며, 특정 회사의 실제 채점표가 아닙니다.

← 전체 질문 보기