[C++] 백준/Platinum/1786. 찾기

2025. 3. 28. 20:55·C++/Coding Test

문제: 찾기 (백준 1786번)

문제 개요

목표

주어진 텍스트 문자열에서 패턴 문자열이 등장하는 모든 위치(인덱스)를 찾아, 등장 횟수와 위치를 출력하는 문제.

핵심 포인트

  • 단순 문자열 검색(브루트포스)은 O(n×m) 시간 복잡도를 가짐
  • KMP (Knuth-Morris-Pratt) 알고리즘을 사용하여 O(n+m) 시간에 해결

1. 패턴 접두사 함수 (KMP 함수)

목적

패턴 문자열 내부에서 각 인덱스까지의 부분 문자열이 가지는 최대 접두사-접미사 일치 길이를 pi 배열에 저장

예시 "ABABC"

인덱스 부분 문자열 접두사-접미사 분석 pi[i]
0 "A" 접두사 길이 0 0
1 "AB" "B"와 "A" 다름 0
2 "ABA" "A" (인덱스 2)와 "A" (인덱스 0) 일치 1
3 "ABAB" 인덱스 3의 'B'와 인덱스 1의 'B' 일치 2
4 "ABABC" 불일치로 인해 재조정 0

KMP 접두사 함수 구현

void Kmp(string& pat)
{
    int n = pat.size();
    pi.resize(n, 0);
    int j = 0;
    for (int i = 1; i < n; i++)
    {
        while (j > 0 && pat[i] != pat[j])
        {
            j = pi[j - 1];
        }
        if (pat[i] == pat[j])
        {
            j++;
        }
        pi[i] = j;
    }
}

주요 로직 설명

  • while문: 불일치 시 이전 접두사 길이로 돌아가 재비교
  • if문: 문자 일치 시 j 증가
  • pi[i] = j; 현재 인덱스까지 일치한 접두사의 최대 길이 저장

2. 텍스트 내 패턴 매칭 (KMP 검색)

목적

텍스트 문자열 내에서 패턴이 나타나는 모든 위치 찾기

예시 시나리오

  • 텍스트: "ABABABCABABABC"
  • 패턴: "ABABC"

매칭 동작 과정

  1. 텍스트 순회 중 매칭 상태
    • j 변수를 사용해 패턴과의 매칭 상태 유지
    • 불일치 발생 시 pi 배열을 통해 효율적으로 재검색

KMP 검색 구현

int main()
{
    int n = str.size();
    int m = pat.size();
    int j = 0;
    vector<int> answer;

    for (int i = 0; i < n; i++)
    {
        while (j > 0 && str[i] != pat[j])
        {
            j = pi[j - 1];
        }
        if (str[i] == pat[j])
        {
            j++;
        }
        if (j == m) // 패턴 전체 매칭
        {
            answer.push_back(i - m + 2); // 1-indexed 위치 저장
            j = pi[j - 1];
        }
    }

    // 결과 출력
    cout << answer.size() << '\n';
    for (const int& pos : answer)
    {
        cout << pos << ' ';
    }
}

주요 로직 설명

  • while문: 텍스트와 패턴 문자 불일치 시 pi 값으로 j 조정
  • if문: 문자 일치 시 j 증가
  • 패턴 완전 매칭 시:
    • 시작 위치를 answer 벡터에 저장
    • j를 재조정하여 연속된 매칭 탐색

'C++ > Coding Test' 카테고리의 다른 글

[C++] 백준/Silver/15549. if  (0) 2025.04.04
[C++] 백준/Gold/1011. Fly me to the Alpha Centauri  (0) 2025.04.02
[C++] LeetCode/Hard/0745-prefix-and-suffix-search  (0) 2025.03.25
[C++] 백준/Gold/2011. 암호코드  (0) 2025.03.19
[C++] 백준/Gold/1915. 가장 큰 정사각형  (0) 2025.03.14
'C++/Coding Test' 카테고리의 다른 글
  • [C++] 백준/Silver/15549. if
  • [C++] 백준/Gold/1011. Fly me to the Alpha Centauri
  • [C++] LeetCode/Hard/0745-prefix-and-suffix-search
  • [C++] 백준/Gold/2011. 암호코드
돼지표
돼지표
https://github.com/wkdgns135
  • 돼지표
    돼지표 개발 스토리
    돼지표
  • 전체
    오늘
    어제
    • 분류 전체보기 (106)
      • C++ (60)
        • Coding Test (53)
        • Study (1)
      • Python (1)
      • Machine Learning (2)
      • Computer Graphics (4)
        • Curly Hair Simulation (2)
      • GPU Programming (11)
        • CUDA basic (7)
        • CUDA fluidsGL (4)
      • Unreal 5 (21)
        • Troubleshooting (4)
        • FPS Shooting (5)
        • Study (10)
        • EOS (1)
      • Computer Science (7)
        • Algorithm (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    정렬
    CUDA
    OpenGL
    FPS
    Algorithm
    UE5
    자료 구조
    Fluid Simulation
    GPU Programming
    unreal 5
    Rendering Pipeline
    위상 정렬
    아이작 맵 생성
    수학
    구현
    CS
    그래프 탐색
    C++
    dp
    BFS
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
돼지표
[C++] 백준/Platinum/1786. 찾기
상단으로

티스토리툴바