본문 바로가기

코딩/알고리즘

백준 1701 Cubeditor


KMP알고리즘을 수행할 때 pi를 구한다.

그런데 만약 pattern에 2번 이상 반복되는 부분 문자열이 있다면 pi에 그 부분문자열의 길이가 기록 된다.


예를들어 pattern이 aabcaa라고 하자.

그렇다면 index가 6일때 접두사와 접미사가 같은 부분이 나오고, pi[6] = 2로 기록된다.

그런데 이 값은 접두사와 접미사가 같은 부분의 길이를 의미하기도 한다. 

따라서 pi[6]의 값은 pi[0~6]의 최대 길이 중복 부분 문자열의 길이(우리가 구하고 싶은 값)가 된다.


또 다른 예로 pattern을 aabcaabxx라고 하자.

이 패턴에서는 index가 6일때 마찬가지로 접두사와 접미사가 같은 부분이 나오고, index가 7일때 또 한번 나온다. (pi[6] = 2, pi[7] = 3)

따라서 pi의 최대값을 체크하면 pattern에서 중복되는 부분문자열의 최대 길이를 알수 있게 된다.


마지막으로 pattern을 caabaac라고 하자. 

이 패턴에서는 pattern[1~5]의 부분문자열에서 aa라는 중복되는 부분문자열이 나온다.

이러한 패턴도 파악하기 위해 우리는 pattern[0~pattern.length]뿐만 아니라, pattern[k~pattern.length], k=0~pattern.length에 대해 

pi를 모두 구한 뒤 최대값을 구할 것이다.




//deque.tistory.com

#include <iostream> 
#include <string> 

using namespace std;

int pi[5002][5002];

int main() {
	string str;
	cin >> str;
	int strlength = str.size();
	int max = 0;
	for (int k = 0; k < strlength; k++) { //pi[k][i]는 str[k]~str[-1]를 pattern이라고 했을때의 pi이다
		string pattern = str.substr(k, strlength);
		int j = 0;
		for (int i = 1; i < pattern.size(); i++) {
			while (j > 0 && pattern[i] != pattern[j]) {
				j = pi[k][j - 1];
			}
			if (pattern[i] == pattern[j]) {
				j++;
				pi[k][i] = j;
			}
		}
		for (int i = 0; i < pattern.size(); i++) {
			if (pi[k][i] > max) max = pi[k][i];
		}
	}

	cout << max << endl;

	return 0;
}








'코딩 > 알고리즘' 카테고리의 다른 글

백준 9248 Suffix Array  (0) 2018.01.14
백준 4354 문자열 제곱  (0) 2018.01.12
[python3] 백준 1786 찾기  (0) 2018.01.12
백준 1015 수열 정렬  (0) 2018.01.10
백준 1016 제곱 ㄴㄴ수  (7) 2018.01.10