[알고리즘 정리] KMP(2/3)

1 분 소요

pi 배열 생성하기

아래 함수는 이전 포스트에서 그림을 통해 그려본 pi 배열을 만드는 과정을 구현한 코드입니다.

static int[] getPi(String pattern) {
	int[] pi = new int[pattern.length()];
	char[] pt = pattern.toCharArray();

	int j = 0;
	for (int i = 1; i < pattern.length(); i++) {
		while (j > 0 && pt[i] != pt[j]) {
			j = pi[j - 1];
		}

		if (p[i] == p[j]) {
			pi[i] = ++j;
		}
	}

	return pi;
}

아래부터는 위 코드가 동작하는 과정을 그림으로 나타낸 것입니다.

j = 0, i = 1

http://dl.dropbox.com/s/s0uwujw7i6cq7s6/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-1.png

pt[i]와 pt[j]가 다르므로 j가 감소해야 하지만, 더 이상 앞으로 갈 곳이 없으니 i만 전진합니다.

j = 0, i = 2

http://dl.dropbox.com/s/62ssus36t2g42gw/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-2.png

pt[i] 와 pt[j] 가 같으므로 pi[i] 에 j를 1 증가시킨 값인 1을 넣어줍니다.

j = 1, i = 3

http://dl.dropbox.com/s/76168ydfqroj7oo/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-3.png

pt[i]와 pt[j]가 같으므로 pi[i]에 j를 1 증가시킨 값인 2를 넣어줍니다.

j = 2, i = 4

http://dl.dropbox.com/s/97xwuupmwl8svkk/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-4.png

pt[i]와 pt[j]가 같으므로 pi[i]에 j를 1 증가시킨 값인 2를 넣어줍니다.

j = 3, i = 5

http://dl.dropbox.com/s/3ronode7unfxjgm/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-5.png

pt[i]와 pt[j]가 다르므로 j가 맞는 위치를 찾아갑니다. 새로운 j는 pi[3-1]인 1이 됩니다.

j = 1, i = 5

http://dl.dropbox.com/s/1gnm9prqixrqn2y/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-6.png

pt[i]와 pt[j]가 다르므로 j가 맞는 위치를 찾아갑니다. 새로운 j는 pi[1-1]인 0이 됩니다.

j = 0, i = 5

http://dl.dropbox.com/s/k91893r2x4vv3vr/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-7.png

pt[i]와 pt[j]가 다르므로 j가 감소해야 하지만, 더 이상 앞으로 갈 곳이 없으니 i만 전진합니다.

j = 0, i = 6

http://dl.dropbox.com/s/kh9pmk4ueaguq6n/%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EC%A0%95%EB%A6%AC-KMP%202-8.png

pt[i]와 pt[j]가 같으므로 pi[i]에 j를 1 증가시킨 값인 1을 넣어줍니다.

인덱스 i는 부분 문자열의 끝을 의미하게 됩니다. i가 3의 위치에 있으면, 부분 문자열 ABAB의 접두사 및 접미사의 최대 공통 길이를 구하여 pi[3] 에 저장하게 됩니다.

인덱스 j는 그 위치까지 맞아떨어진 접두사의 앞과 접미사의 앞의 문자 개수를 기억하고 있습니다. 따라서 pt[i] 와 pt[j] 만 같으면 접두사 및 접미사의 최대 공통 길이는 j가 기억하고 있는 개수(j 그 자체)에서 1 증가하게 되는 것입니다.

카테고리:

업데이트:

댓글남기기