알고리즘
KMP
parkit
2020. 6. 23. 16:05
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
반응형