입력받는 문자열 T, P의 최대 길이가 100만으로 굉장히 길기 때문에 O(NM) 알고리즘으로 풀 수 없다.
따라서 시간복잡도가 O(N+M)인 KMP-algorithm을 구현하여 풀었다.
추가로 공백을 포함하는 문자열을 입력받기 위해 cin 함수가 아닌 getline(cin, str) 함수를 사용하였다.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<int> getPartialMatch(const string& P)
{
int Plen = P.length();
vector<int> pi(Plen, 0);
int begin = 1, matched = 0;
while (begin + matched < Plen)
{
if (P[begin + matched] == P[matched])
{
matched++;
pi[begin + matched - 1] = matched;
}
else
{
if (matched == 0)
begin++;
else
{
begin += matched - pi[matched - 1];
matched = pi[matched - 1];
}
}
}
return pi;
}
vector<int> KMPsearch(const string& T, const string& P)
{
int Tlen = T.length(), Plen = P.length();
vector<int> pos;
vector<int> pi = getPartialMatch(P);
int begin = 0, matched = 0;
while (begin <= Tlen - Plen)
{
if (T[begin + matched] == P[matched])
{
matched++;
if (matched == Plen)
pos.push_back(begin + 1);
}
else
{
if (matched == 0)
begin++;
else
{
begin += matched - pi[matched - 1];
matched = pi[matched - 1];
}
}
}
return pos;
}
int main(void)
{
string T, P;
getline(cin, T);
getline(cin, P);
vector<int> result = KMPsearch(T, P);
cout << result.size() << endl;
for (int i = 0; i < result.size(); i++)
cout << result[i] << ' ';
return 0;
}
알고리즘 200일 프로젝트 - 137 day
'알고리즘 > BOJ' 카테고리의 다른 글
백준 2667번: 단지번호붙이기 (0) | 2020.09.19 |
---|---|
백준 2178번: 미로 탐색 (0) | 2020.09.19 |
백준 1062번: 가르침 (비트마스크) (0) | 2020.08.20 |
백준 2212번: 센서 (0) | 2020.08.19 |
백준 1041번: 주사위 (0) | 2020.08.17 |