반응형
https://www.acmicpc.net/problem/1786
1786번: 찾기
첫째 줄에, T 중간에 P가 몇 번 나타나는지를 나타내는 음이 아닌 정수를 출력한다. 둘째 줄에는 P가 나타나는 위치를 차례대로 공백으로 구분해 출력한다. 예컨대, T의 i~i+m-1번 문자와 P의 1~m
www.acmicpc.net
[ 문제풀이 ]
이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 걸 추천드립니다!
https://rudalsd.tistory.com/69?category=1064608
[ 알고리즘 ] KMP 알고리즘(KMP Algorithm)
KMP 알고리즘은 문자열을 탐색하는 알고리즘입니다. 보통 ctrl + f를 이용하여 원하는 문자열을 찾을 때 많이 쓰는 방식입니다. 단순하게 길이가 N인 문자열의 처음부터 끝까지 문자열의 길이가 M
rudalsd.tistory.com
입력되는 문자열에 공백이 포함되어 있으므로 getline(cin, string) 함수를 사용해서 값을 입력받은 후 KMP 알고리즘을 활용하여 문제를 풀면 됩니다.
[ 소스 코드 ]
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 52 53 54 55 56 57 58 59 60 | #include<iostream> #include<string> #include<vector> using namespace std; string T, P; vector<int> Pi; vector<int> ans; void findK(string P) //찾을 문자열 P 전처리 { Pi.resize(P.size()); int cur = 0; for (int i = 1; i < P.size(); i++) { while (P[i] != P[cur] && cur > 0) { cur = Pi[cur - 1]; } if (P[i] == P[cur]) { Pi[i] = cur + 1; cur++; } } } void KMP(string T, string P) //T에서 P찾기 { int cur = 0; for (int i = 0; i < T.size(); i++) { while (cur > 0 && T[i] != P[cur]) { cur = Pi[cur - 1]; } if (T[i] == P[cur]) { if (cur == P.size() - 1) { ans.push_back(i - cur + 1); cur = Pi[cur]; } else { cur++; } } } } int main() { getline(cin, T); getline(cin, P); findK(P); KMP(T, P); cout << ans.size() << endl; for (int i = 0; i < ans.size(); i++) { cout << ans[i] << " "; } } | cs |
반응형
'백준' 카테고리의 다른 글
[ 백준 ] 1948번 - 임계경로 (C++) (0) | 2022.07.22 |
---|---|
[ 백준 ] 10830번 - 행렬 제곱 (C++) (0) | 2022.07.21 |
[ 백준 ] 1761번 - 정점들의 거리 (C++) (0) | 2022.07.18 |
[ 백준 ] 1708번 - 볼록 껍질 (C++) (0) | 2022.07.17 |
[ 백준 ] 1086번 - 박성원 (C++) (0) | 2022.07.15 |