π™†π™ˆπ™‹

uuuouuoΒ·2022λ…„ 7μ›” 28일
0
post-thumbnail

KMP μ•Œκ³ λ¦¬μ¦˜


  • 접두사와 μ ‘λ―Έμ‚¬μ˜ κ°œλ…μ„ ν™œμš”ν•˜μ—¬ 'λ°˜λ³΅λ˜λŠ” 연산을 μ–Όλ§ˆλ‚˜ 쀄일 수 μžˆλŠ”μ§€' νŒλ³„ν•˜μ—¬ 맀칭할 λ¬Έμžμ—΄μ„ λΉ λ₯΄κ²Œ μ ν”„ν•˜λŠ” 기법 (참고링크)

문제 적용 : SWEA 단어가 λ“±μž₯ν•˜λŠ” 횟수


import java.io.*;

public class 단어가등μž₯ν•˜λŠ”νšŸμˆ˜ {

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        int T = Integer.parseInt(br.readLine());

        for (int t = 1; t <= T; t++) {
            sb.append("#" + t + " ");

            String content = br.readLine();
            String word = br.readLine();
            int n = content.length();
            int m = word.length();

            int[] pi = new int[m];
            int answer = 0;
            int idx = 0; // μΌμΉ˜ν•œ κΈ€μž 수

            for (int i = 1; i < m; i++) {
                // λ§žλŠ” μœ„μΉ˜κ°€ λ‚˜μ˜¬ λ•ŒκΉŒμ§€ idx - 1칸의 곡톡 λΆ€λΆ„ μœ„μΉ˜λ‘œ 이동
                while (idx > 0 && word.charAt(i) != word.charAt(idx))
                    idx = pi[idx - 1];

                // λ§žμ„ 경우 i 길이 λ¬Έμžμ—΄μ˜ 곡톡 κΈΈμ΄λŠ” idxμœ„μΉ˜ +1
                if (word.charAt(i) == word.charAt(idx)) {
                    idx += 1;
                    pi[i] = idx;
                }
            }

            idx = 0;
            for (int i = 0; i < n; i++) {
                // λ§žλŠ” μœ„μΉ˜κ°€ λ‚˜μ˜¬ λ•ŒκΉŒμ§€ j - 1칸의 곡톡 λΆ€λΆ„ μœ„μΉ˜λ‘œ 이동
                while (idx > 0 && content.charAt(i) != word.charAt(idx)) {
                    idx = pi[idx - 1];
                }
                // λ§žλŠ” 경우
                if (content.charAt(i) == word.charAt(idx)) {
                    if (idx == m - 1) {
                        answer++;
                        idx = pi[idx];
                    }
                    // λ§žμ•˜μ§€λ§Œ νŒ¨ν„΄μ΄ λλ‚˜μ§€ μ•Šμ•˜λ‹€λ©΄ idxλ₯Ό ν•˜λ‚˜ 증가
                    else
                        idx++;
                }
            }

            sb.append(answer + "\n");
        }
        System.out.println(sb);
    }

}

0개의 λŒ“κΈ€