1 25 26 package org.gjt.sp.jedit.search; 27 28 32 public class BoyerMooreSearchMatcher extends SearchMatcher 33 { 34 40 public BoyerMooreSearchMatcher(String pattern, boolean ignoreCase) 41 { 42 this.pattern = pattern.toCharArray(); 43 if(ignoreCase) 44 { 45 for(int i = 0; i < this.pattern.length; i++) 46 { 47 this.pattern[i] = Character.toUpperCase( 48 this.pattern[i]); 49 } 50 } 51 52 this.ignoreCase = ignoreCase; 53 54 pattern_end = this.pattern.length - 1; 55 } 57 74 public SearchMatcher.Match nextMatch(CharSequence text, 75 boolean start, boolean end, boolean firstTime, 76 boolean reverse) 77 { 78 int pos = match(text,reverse); 79 80 if (pos == -1) 81 { 82 return null; 83 } 84 else 85 { 86 returnValue.start = pos; 87 returnValue.end = pos + pattern.length; 88 return returnValue; 89 } 90 } 92 101 public int match(CharSequence text, boolean reverse) 102 { 103 int[] skip, suffix; 107 if(reverse) 108 { 109 if(back_skip == null) 110 { 111 back_skip = generateSkipArray(true); 112 back_suffix = generateSuffixArray(true); 113 } 114 skip = back_skip; 115 suffix = back_suffix; 116 } 117 else 118 { 119 if(fwd_skip == null) 120 { 121 fwd_skip = generateSkipArray(false); 122 fwd_suffix = generateSuffixArray(false); 123 } 124 skip = fwd_skip; 125 suffix = fwd_suffix; 126 } 128 int pos; 130 131 int anchor = 0; 133 134 141 char ch = 0; 142 143 int bad_char; 144 int good_suffix; 145 146 SEARCH: 157 while (anchor + pattern_end < text.length()) 158 { 159 for (pos = pattern_end; pos >= 0; --pos) 160 { 161 ch = text.charAt(pos + anchor); 162 if(ignoreCase) 163 ch = Character.toUpperCase(ch); 164 165 if ((reverse ? ch != pattern[pattern_end - pos] 167 : ch != pattern[pos])) 168 { 169 171 bad_char = pos - skip[getSkipIndex(ch)]; 173 174 good_suffix = suffix[pos]; 176 177 int skip_index = (bad_char > good_suffix) ? bad_char : good_suffix; 180 anchor += skip_index; 181 182 continue SEARCH; 184 } 185 } 186 187 return anchor; 189 } 190 191 return -1; 193 } 195 public String toString() 197 { 198 return "BoyerMooreSearchMatcher[" + new String (pattern) + ']'; 199 } 201 private char[] pattern; 203 private int pattern_end; 204 private boolean ignoreCase; 205 206 private int[] fwd_skip; 208 private int[] fwd_suffix; 209 private int[] back_skip; 210 private int[] back_suffix; 211 213 215 221 private int[] generateSkipArray(boolean reverse) 222 { 223 int[] skip = new int[256]; 225 226 if (pattern.length == 0) 228 return skip; 229 230 int pos = 0; 231 232 do 233 { 234 skip[getSkipIndex(pattern[reverse ? pattern_end - pos : pos])] = pos; 235 } 236 while (++pos < pattern.length); 237 238 return skip; 239 } 241 258 private static final int getSkipIndex(char ch) 259 { 260 return ch & 0x000000FF; 261 } 263 268 private int[] generateSuffixArray(boolean reverse) 269 { 270 int m = pattern.length; 271 272 int j = m + 1; 273 274 int[] suffix = new int[j]; 275 int[] tmp = new int[j]; 276 tmp[m] = j; 277 278 for (int i = m; i > 0; --i) 279 { 280 while (j <= m && pattern[reverse ? pattern_end - i + 1 : i - 1] 281 != pattern[reverse ? pattern_end - j + 1 : j - 1]) 282 { 283 if (suffix[j] == 0) 284 { 285 suffix[j] = j - i; 286 } 287 288 j = tmp[j]; 289 } 290 291 tmp[i - 1] = --j; 292 } 293 294 int k = tmp[0]; 295 296 for (j = 0; j <= m; j++) 297 { 298 if (j > 0) 302 { 303 suffix[j - 1] = (suffix[j] == 0) ? k : suffix[j]; 304 } 305 306 if (j == k) 307 { 308 k = tmp[k]; 309 } 310 } 311 312 return suffix; 313 } 315 } 317 | Popular Tags |