알고리즘 공부/문제 풀이
[JAVA] 백준 1786 찾기
valid_ming
2021. 9. 23. 17:15
https://www.acmicpc.net/problem/1786
1786번: 찾기
첫째 줄에, T 중간에 P가 몇 번 나타나는지를 나타내는 음이 아닌 정수를 출력한다. 둘째 줄에는 P가 나타나는 위치를 차례대로 공백으로 구분해 출력한다. 예컨대, T의 i~i+m-1번 문자와 P의 1~m
www.acmicpc.net


풀이


코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
public class Main {
public static void main(String[] args) throws Exception {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
char[] text = in.readLine().toCharArray();
char[] pattern = in.readLine().toCharArray();
int tLength = text.length, pLength = pattern.length;
int[] pi = new int[pLength]; //패턴 포인터를 어디로 옮겨야하는지 인덱스 저장
for(int i=1, j=0; i<pLength; i++){// i:접미사 포인터, j:접두사 포인터
while(j>0 && pattern[i] != pattern[j]) {
j = pi[j-1]; //j에서 문자가 다르다! -> j-1까지는 동일하다, pi[j-1]로 j 포인터를 이동
}
if(pattern[i]==pattern[j]) pi[i] = ++j; //j와 i는 일치하면 j 증가, 길이는 j+1
else pi[i] = 0; //일치하지 않는다면 j 그자리에
}
int cnt = 0;
// i : 텍스트 포인터 , j: 패턴 포인터
for(int i=0,j=0; i<tLength; ++i) {
while(j>0 && text[i] != pattern[j]) j = pi[j-1];
if(text[i] == pattern[j]) { //두 글자 일치
if(j == pLength-1) { // j가 패턴의 마지막 인덱스라면
cnt++; // 카운트 증가
sb.append((i+1)-pLength+1).append('\n');
j=pi[j];
}else { // 패턴 앞쪽 일치하며 진행중인 상황
j++;
}
}
}
System.out.println(cnt);
System.out.println(sb);
}
}