키워드
어떤 문자열 내에서 부분 문자열이 두 번 이상 나오는 문자열을 찾는 기능
이러한 부분 문자열 중에서 가장 길이가 긴 것을 구하는 프로그램
구현
kmp 알고리즘을 이용하여 구현한다.
하지만 메모리를 보면 알 수 있듯이 메모리가 빠듯한 것을 알 수 있다.
따라서 기존 List를 이용하는 대신 int형 배열을 이용한다.
String도 최대한 Buffer를 이용하여 구현한다.
여기서는 kmpSearcg를 사용하지 않는데, getPartialMatch에서 해당 메서드 자체가 pi[i]=N[..i]의 접미사도 되고 접두사도 되는 문자열의 최대 길이 이므로, 해당 값이 2번 나오는 문자열의 최대 길이와 일치한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class java_1701 {
// pi[i]=N[..i]의 접미사도 되고 접두사도 되는 문자열의 최대 길이
static int getPartialMatch(CharSequence N) {
int m = N.length();
int pi[] = new int[m];
// KMP로 자기 자신을 찾는다.
// N을 N에서 찾는다. begin=0이면 자기 자신을 찾아버리니까 의미 없음
int begin = 1, matched = 0;
// 비교할 문자가 N의 끝에 도달할 때까지 찾으면서 부분 일치를 모두 기록한다.
while (begin + matched < m) {
// 현재 문자가 일치하는가?
if (N.charAt(begin + matched) == N.charAt(matched)) {
matched++;
// 문자열의 갱신된 길이 반환
pi[begin + matched - 1] = matched;
}
// 일치하지 않는다면 -> 다음 문자부터 비교 시작
else {
// 일치한게 없었다면 -> 단순 다음 문자부터
if (matched == 0) {
begin++;
}
// 일치한게 존재했다면..이전 값을 이용하여 갱신해주기
else {
begin += matched - pi[matched - 1];
matched = pi[matched - 1];
}
}
}
int result = 0;
for (int i = 0; i < pi.length; i++) {
result = Math.max(result, pi[i]);
}
return result;
}
public static void main(String[] args) throws IOException {
// 가장 긴 문자열(length-1)부터 부분 문자열이 있는지 찾아보자
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuffer N = new StringBuffer(br.readLine());
int result = solution(N);
System.out.println(result);
br.close();
}
// N의 부분 문자열 중 2번 이상 나오는 문자열의 최대 길이 반환
private static int solution(StringBuffer hayStack) {
int result = 0;
// 길이는 N.length()-1부터 시작한다.
for (int startIndex = 0; startIndex < hayStack.length(); startIndex++) {
CharSequence needle = hayStack.subSequence(startIndex, hayStack.length());
result = Math.max(result, getPartialMatch(needle));
}
return result;
}
}
Uploaded by N2T
'Coding Test > BOJ' 카테고리의 다른 글
[BOJ/JAVA] 1711번: 직각삼각형 (0) | 2023.04.03 |
---|---|
[BOJ/JAVA] 11758번: CCW (0) | 2023.04.03 |
[BOJ/JAVA] 1599번: 민식어 (0) | 2023.03.20 |
[BOJ/JAVA] 17609번: 회문 (0) | 2023.03.20 |
[BOJ/JAVA] 1958번: LCS 3 (0) | 2023.03.20 |