코테/백준

[백준/JAVA] 16916번: 부분 문자열

imname1am 2023. 5. 22. 23:18
반응형

🔺 문제

 

16916번: 부분 문자열

첫째 줄에 문자열 S, 둘째 줄에 문자열 P가 주어진다. 두 문자열은 빈 문자열이 아니며, 길이는 100만을 넘지 않는다. 또, 알파벳 소문자로만 이루어져 있다.

www.acmicpc.net

 

 

🔺 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.util.*;
import java.io.*;
 
public class Main {
    static int[] pi; // 패턴 일치 저장 배열
    
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        String S = br.readLine();
        String P = br.readLine();
        
        makePi(P);    
        System.out.println(KMP(S, P));
    }
    
    // 패턴 일치 저장 배열
    public static void makePi(String pattern) {
        pi = new int[pattern.length()];
        
        int idx = 0;
        for(int i = 1 ; i < pattern.length() ; i++) {
            // idx > 0 : 문자열 매칭 시작
            // 연속으로 일치하지 않으면, j-1칸의 공통 부분 위치로 이동
            while(idx > 0 && pattern.charAt(i) != pattern.charAt(idx)) {
                idx = pi[idx - 1];
            }
            
            // 맞는 경우
            if(pattern.charAt(i) == pattern.charAt(idx)) {
                // i 길이 문자열의 공통 길이 = j의 위치 + 1
                idx++;
                pi[i] = idx;
                
                // == pi[i] = ++idx;
            }
        }
    }
    
    // 문자열 매칭
    public static int KMP(String str, String pattern) {
        int idx = 0;    // 패턴 내 일치 체크 idx
        
        for(int i = 0 ; i < str.length() ; i++) {
            // 맞는 위치가 나올 때까지 j-1칸의 공통 부분 위치로 이동
            while(idx > 0 && str.charAt(i) != pattern.charAt(idx)) {
                idx = pi[idx - 1];
            }
            
            // 맞는 경우
            if(str.charAt(i) == pattern.charAt(idx)) {
                if(idx == pattern.length() - 1) {   // 패턴 끝까지 확인했으면 정답
                    idx = pi[idx];
                    return 1;
                }
                else {  // 맞았지만, 패턴이 끝나지 않았다면 패턴의 다음 문자 확인
                    idx++;
                }
            }
        }
        return 0;
    }
}
cs
✅ 해결 아이디어
✔ KMP 문자열 매칭 알고리즘

과정 설명은 타 블로그에서 너무 잘 하셔서 그거 보는 게 더 좋을 듯...

(밑에 참고 링크 남김)

 


💬 느낀 점

오...

사실 contains 쓸 수도 있지만

KMP 뼈대문제라고 하셔서

KMP 알고리즘 배우고 다른 분 코드 보고 작성했다.

 

KMP 책에서는 못 보고 처음 보고 이해하느라 시간이 좀 걸렸다...만

앞으로 자주 쓰고 익숙해지면 좋겠따...!

 

 

 

1회독 2회독 3회독 4회독 5회독
V        

(참고)

✔ 감격적인 과정 설명...ㅠㅠㅠ 덕분에 KMP알고리즘을 이해했다... (복습용!)

 

[알고리즘 정리] KMP, 문자열 패턴 매칭 알고리즘

다룰 내용 Brute-Force로 패턴 매칭 KMP 알고리즘이란 무엇인가? KMP 알고리즘 구현 Brute-Force로 패턴 매칭 기존에 있는 문자열을 처음부터 끝까지 차례대로 순회하면서 패턴과 일치하는지 일일이 확

devje8.tistory.com

 

 

[알고리즘] 문자열 매칭 알고리즘 KMP (Java)

문자열 매칭 알고리즘 특정한 글이 있을 때 그 글 안에서 하나의 문자열을 찾는 알고리즘이다. 워드파일 또는 웹 브라우저 DB에서 문자열을 검색할 때 패턴 매칭 알고리즘을 사용하여 검색 결과

loosie.tistory.com

 

[알고리즘] 문자열 검색 알고리즘 KMP 자바 구현하기 (백준 16916)

문자열 단순 비교 문자열 검색 시 주어진 문자열이 ABACAABA 주어진 패턴이 ABACAB 인 경우를 가정하자. 일반적인 방식으로 비교할 경우 A B A C A A B A A B A C A B 문자 하나씩 비교하면 앞의 5가지 문자

hanyeop.tistory.com

 

 

✔ 풀이 참고

 

[알고리즘] 문자열 검색 알고리즘 KMP 자바 구현하기 (백준 16916)

문자열 단순 비교 문자열 검색 시 주어진 문자열이 ABACAABA 주어진 패턴이 ABACAB 인 경우를 가정하자. 일반적인 방식으로 비교할 경우 A B A C A A B A A B A C A B 문자 하나씩 비교하면 앞의 5가지 문자

hanyeop.tistory.com

 

반응형