문제링크 🚩
https://www.acmicpc.net/problem/1786
📕 문제 접근 📕
- 가장 이상적인 KMP문제인 것 같다
- 접미사와 접두사가 같은 영역을 찾기 위한 table을 만들고
- 이를 KMP 알고리즘에 대입하여 해결하면 되는 문제다
- KMP 알고리즘은 해당 포스팅에 자세하게 정리해뒀으니 참고 바란다.
https://security-gom.tistory.com/36
💻 Code 💻
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BOJ_1786_찾기 {
public static int[] makeTable(String p){
int plen = p.length();
int[] table = new int[plen];
int j = 0;
for (int i = 1; i < plen; i++) {
// a b a c
while(j > 0 && p.charAt(i) != p.charAt(j)){
// 문자열 매칭 시작
// 연속 일치 하지 않으면 j 값을 돌려주어 다시 매칭 시작
j = table[j -1];
}
if(p.charAt(i) == p.charAt(j)){
table[i] = ++j;
}
}
return table;
}
public static void KMP(String str, String pattern) {
StringBuilder sb = new StringBuilder();
int cnt = 0;
int[] table = makeTable(pattern);
int sLen = str.length();
int pLen = pattern.length();
int idx = 0; // 현재 대응되는 글자 수
for (int i = 0; i < sLen; i++) {
// idx번째 글자와 짚더미의 해당 글자가 불일치할 경우
// 현재 대응된 글자의 수를 table[idx - 1]번으로 줄임
while (idx > 0 && str.charAt(i) != pattern.charAt(idx)) {
idx = table[idx - 1];
}
// 글자가 대응될 경우
if (str.charAt(i) == pattern.charAt(idx)) {
if (idx == pLen - 1) {
cnt++;
// parent 문자열과 pattern 문자열이 일치하기 시작한 시점을 출력
sb.append(i - idx + 1 + "\n");
idx = table[idx];
}
else {
idx++;
}
}
}
System.out.println(cnt);
System.out.println(sb.toString());
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s1 = br.readLine();
String s2 = br.readLine();
KMP(s1, s2);
}
}
📖 회고 📖
- KMP 를 처음 학습하고 적용하기에 가장 적합한 문제 인 것 같다 .
'JAVA > Algo 풀이' 카테고리의 다른 글
[백준] 4354 문자열 제곱 - KMP(JAVA) (0) | 2023.08.06 |
---|---|
[백준] 1305 광고 - KMP(JAVA) (0) | 2023.08.05 |
[프로그래머스] 야근지수 - JAVA (0) | 2023.08.01 |
[프로그래머스] 110 옮기기 - Java (0) | 2023.08.01 |
[프로그래머스] 이중우선순위큐 - TreeMap (0) | 2023.07.26 |