알고리즘 문제/[백준]

[백준] 1786 찾기

latter2005 2021. 3. 2. 23:46
 

1786번: 찾기

첫째 줄에, T 중간에 P가 몇 번 나타나는지를 나타내는 음이 아닌 정수를 출력한다. 둘째 줄에는 P가 나타나는 위치를 차례대로 공백으로 구분해 출력한다. 예컨대, T의 i~i+m-1번 문자와 P의 1~m

www.acmicpc.net

문제 확인

 

스트링에서 패턴 스트링을 찾는 문제는 대부분 kmp 알고리즘으로 풀 수 있습니다.

 

풀이

 

kmp 알고리즘을 그대로 적용하면 풀리는 문제입니다.

 

커누스-모리스-프랫 알고리즘 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 과학에서, 커누스-모리스-프랫 알고리즘(Knuth–Morris–Pratt algorithm, KMP)은 문자열 중에 특정 패턴을 찾아내는 문자열 검색 알고리즘의 하나이다. 문자열

ko.wikipedia.org

 

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
 
void fail_func(vector<int> &fail, string &s) {
    int n = s.length();
    for (int i = 1, m = 0; i < n; ++i) {
        if (s[i] == s[m])
            fail[i] = ++m;
        else if (m != 0) {
            --i;
            m = fail[m - 1];
        }
    }
}
vector<int> kmp(string &str, string &p) {
    int str_len = str.length(), p_len = p.length();
    vector<int> res, fail(p_len);
    fail_func(fail, p);
    for (int i = 0, m = 0; i < str_len; ++i) {
        if (str[i] == p[m]) {
            if (++== p_len)
                res.push_back(i - p_len + 1);
        }
 
        else if (m != 0) {
            --i;
            m = fail[m - 1];
        }
    }
    return res;
}
 
int main() {
    cin.tie(NULL); cout.tie(NULL);
    ios::sync_with_stdio(false);
    string str, p;
    getline(cin, str);
    getline(cin, p);
 
    
    auto res = kmp(str, p);
    cout << res.size() << '\n';
    for (int t : res) {
        cout << t + 1 << ' ';
    }
 
}
cs
반응형

'알고리즘 문제 > [백준]' 카테고리의 다른 글

[백준] 1662 압축  (0) 2021.03.04
[백준] 1937 욕심쟁이 판다  (0) 2021.03.04
[백준] 1298 노트북의 주인을 찾아서  (0) 2021.02.22
[백준] 14245 XOR  (0) 2021.02.22
[백준] 1915 가장 큰 정사각형  (0) 2021.02.22