백준 5525 - IOIOI
Updated:
Java
5525 번 - IOIOI
문제
접근 방법
KMP 알고리즘을 사용하여, 주어진 문자열에서 일치하는 패턴의 개수를 세었다.
코드
import java.util.*;
import java.io.*;
public class Main {
static int n, m, result;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stk;
n = stoi(br.readLine());
m = stoi(br.readLine());
char[] str = br.readLine().toCharArray();
StringBuilder sb = new StringBuilder();
sb.append('I');
for(int i = 0; i < n; i++) {
sb.append("OI");
}
char[] pattern = sb.toString().toCharArray();
int plen = pattern.length;
// 실패함수 만들기
// i:접미사 포인터(i=1부터 시작: 우리는 실패함수를 만드는게 목적이므로 첫글자 틀리면 0위치로 가야하므로.)
// i는 계속 한칸 씩 증가한다.
// j:접두사 포인터
// 만약 현재 j가 가리키는 접두사와 i가 가리키는 접미사가 같으면, i와 j를 동시에 증가시키고
// 현재 접두사와 접미사가 다르면, j는 실패함수에 따라 뒤로 간다.
int[] fail = new int[plen];
for(int i = 1, j = 0; i < plen; i++) {
while(j > 0 && pattern[i] != pattern[j]) {
j = fail[j - 1];
}
if(pattern[i] == pattern[j])
fail[i] = ++j;
}
int slen = str.length;
// 실제 패턴과 문자열 비교, i는 앞으로 한칸 씩만 움직이고, j가 왔다갔다 한다.
for(int i = 0, j = 0; i < slen; i++) {
while(j > 0 && str[i] != pattern[j])
j = fail[j - 1];
if(str[i] == pattern[j]) {
if(j == plen - 1) {
result++;
j = fail[j];
}
else
j++;
}
}
System.out.println(result);
br.close();
}
static int stoi(String str) {
return Integer.parseInt(str);
}
}
총평
후기
KMP를 자주 복습