어흥
[백준 1786] 찾기 (JAVA) 본문
728x90
반응형
문제 링크: https://www.acmicpc.net/problem/1786
1786번: 찾기
첫째 줄에, T 중간에 P가 몇 번 나타나는지를 나타내는 음이 아닌 정수를 출력한다. 둘째 줄에는 P가 나타나는 위치를 차례대로 출력한다. 예컨대, T의 i~i+m-1번 문자와 P의 1~m번 문자가 차례로 일치한다면, i를 출력하는 식이다.
www.acmicpc.net
1. 주의할 점
- KMP 알고리즘에 대하여 알고 있어야 한다
- 공백 문자도 받을 수 있어야 한다
- 애매하게 알고 있다면 이전 게시글을 참고한다 https://imnotabear.tistory.com/117
[백준 16916] 부분 문자열 (JAVA)
문제 링크: https://www.acmicpc.net/problem/16916 16916번: 부분 문자열 첫째 줄에 문자열 S, 둘째 줄에 문자열 P가 주어진다. 두 문자열은 빈 문자열이 아니며, 길이는 100만을 넘지 않는다. 또, 알파벳 소문자..
imnotabear.tistory.com
- 아예 모르면 위키피디아를 통해 KMP 알고리즘에 대해 공부하고 다시 문제를 풀도록 한다
2. 구현
- KMP 알고리즘을 통하여 구현한다
- 일치하는 문자열이 있는 경우, Cnt++를 시키고, 해당 Index를 Li 리스트에 담는다
- 모두 검사한 후, Cnt와 Li에 있는 원소를 전부 출력한다
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
public class Main_bj_1786_찾기 {
static int cnt=0;
static List<Integer> li;
static int[] getPi(String ptn) {
int[] pi = new int[ptn.length()];
int j=0;
for(int i=1;i<ptn.length();i++) {
while(j>0 && ptn.charAt(i)!=ptn.charAt(j)) {
j=pi[j-1];
}
if(ptn.charAt(i)==ptn.charAt(j))
pi[i]=++j;
}
return pi;
}
static void KMP(String org, String ptn) {
int pi[] = getPi(ptn);
int j=0;
for(int i=0;i<org.length();i++) {
while(j>0 && org.charAt(i)!=ptn.charAt(j)) {
j = pi[j-1];
}
if(org.charAt(i)==ptn.charAt(j)) {
if(j==ptn.length()-1) {
++cnt;
li.add(i-j+1);
j=pi[j];
}
else
j++;
}
}
}
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String origin = br.readLine();
String pattern = br.readLine();
li = new ArrayList<>();
KMP(origin,pattern);
System.out.println(cnt);
for(int i=0;i<cnt;i++)
System.out.println(li.get(i));
}
}
728x90
반응형
'알고리즘 > 백준' 카테고리의 다른 글
[백준 1504] 특정한 최단 경로 (C++) (0) | 2020.04.14 |
---|---|
[백준 1701] Cubeditor (C++) (0) | 2020.04.12 |
[백준 16916] 부분 문자열 (JAVA) (0) | 2020.04.10 |
[백준 9938] 방 청소 (C++) (0) | 2020.04.10 |
[백준 10775] 공항 (C++) (0) | 2020.04.10 |
Comments