반응형
Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 성적평가
- 연결요소
- 처우산정
- BOJ
- 퇴사통보
- dfs
- @P0
- 파라메트릭
- upper_bound
- 기술면접
- softeer
- 물채우기
- incr
- 소프티어
- 경력
- compose
- boj #19237 #어른 상어
- 백준
- 이분탐색
- 오퍼레터
- msSQL
- 매개변수탐색
- Kafka
- BFS
- 처우협의
- 13908
- Docker
- OFFSET
- 6987
- 백트래킹
Archives
- Today
- Total
기술 블로그
KMP 본문
728x90
반응형
문자열 매칭 알고리즘 : KMP
KMP 알고리즘은 접두사와 접미사의 개념을 활용하여 ‘반복되는 연산을 얼마나 줄일 수 있는지’를 판별하여, 매칭할 문자열을 빠르게 건너뛰는 기법이다.
makeTable() : 접두사와 접미사의 개념을 활용한 최대 일치 길이를 찾는 함수
연습 문제
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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | import java.io.*; import java.util.*; public class Solution { static BufferedReader br; static BufferedWriter bw; // table 구축 static Vector<Integer> makeTable(String pattern) { int patternSize = pattern.length(); Vector<Integer> table = new Vector<Integer>(); for(int i=0; i<patternSize; i++) { table.add(0); } int j = 0; /* 일치하는 경우에는 i와 j 둘 다 증가시켜준다. * 일치하지 않는 경우에는 i는 증가, j는 현재 table 내에서 (j-1)번 째 인덱스의 값으로 바꿔준다. */ for(int i=1; i<patternSize; i++) { while(j > 0 && pattern.charAt(i) != pattern.charAt(j)) { j = table.get(j - 1); } if(pattern.charAt(i) == pattern.charAt(j)) { table.set(i, ++j); } } return table; } /* 매칭이 이루어지지 않는(실패한) 인덱스(index)에서 1을 뺀 인덱스(index - 1)가 가리키는 * 그 값으로 j를 이동시킨다. * i는 계속 앞으로 나아가기만 하면 된다. */ static void kmp(String parent, String pattern) { Vector<Integer> table = new Vector<Integer>(); table = makeTable(pattern); int parentSize = parent.length(); int patternSize = pattern.length(); int j = 0; for(int i=0; i<parentSize; i++) { while(j > 0 && parent.charAt(i) != pattern.charAt(j)) { j = table.get(j - 1); } if(parent.charAt(i) == pattern.charAt(j)) { if(j == patternSize - 1) { System.out.println(i - patternSize + 2 + "번 째에서 찾았습니다."); j = table.get(j); // 찾은 뒤에도 점프 } else { ++j; } } } } public static void main(String[] args) throws IOException { // TODO Auto-generated method stub br = new BufferedReader(new InputStreamReader(System.in)); bw = new BufferedWriter(new OutputStreamWriter(System.out)); StringTokenizer st; //st = new StringTokenizer(br.readLine()); String parent = "ababacabacaabacaaba"; String pattern = "abacaaba"; kmp(parent, pattern); bw.write("\n"); bw.flush(); bw.close(); } } class pair { int first, second; pair(int a, int b) { this.first = a; this.second = b; } } class tuple { int first, second, third; tuple(int a, int b, int c) { this.first = a; this.second = b; this.third = c; } } class PQ implements Comparable<PQ> { int first, second, third; PQ(int f, int s, int t) { this.first = f; this.second = s; this.third = t; } public int compareTo(PQ p) { if(this.first < p.first) { return -1; // 오름차순 } else if(this.first == p.first) { if(this.second < p.second) { return -1; } else if(this.second == p.second) { if(this.third < p.third) { return -1; } } } return 1; // 이미 this.first가 더 큰 것이 됐으므로, 1로 해준다. // -1로 하면 결과가 이상하게 출력됨. } } | cs |
728x90
반응형
'알고리즘' 카테고리의 다른 글
쿼리(연산)를 누적하여 마지막 한 번에 연산하기(feat. 누적합) (0) | 2021.09.14 |
---|---|
단절점과 단절선 (0) | 2020.03.06 |
Exchange arguments (sorting with dp) (0) | 2020.02.28 |
고속 거듭제곱 알고리즘(18291번 비요뜨의 징검다리 건너기, 1629번 곱셈) (0) | 2020.02.27 |
직사각형에서 대각선이 통과하는 정사각형의 개수는? (0) | 2020.01.10 |