字符串搜索的KMP算法实现(java版)
刚才看到新闻频道转截的一篇文章:阮一峰:字符串匹配的KMP算法,图文并茂通俗易懂,就用java实现了一下
对于我这个只会排序算法的人来说,也算是一个比较难的任务了。
上次写的逻辑有问题,这次不知道有没有bug。
1 /** 2 * Knuth-Morris-Pratt 算法 3 * 4 * @author yinqi 5 * @date 2013-5-5 - 上午11:11:56 6 */ 7 public class StringSearchKMP { 8 9 /** 10 * @param args 11 */ 12 public static void main(String[] args) { 13 int index = knuthMorrisPratt("ABCDABABCDAABCDABCABCDABDABD", 14 "ABCDABDABD", 0); 15 System.out.println(index); 16 } 17 18 /** 19 * 字符串搜索KMP算法 <br> 20 * 21 * @param searchStr 22 * @param matchStr 23 * @param start 24 * @return 25 */ 26 public static int knuthMorrisPratt(String searchStr, String matchStr, 27 int start) { 28 char[] searchchar = searchStr.toCharArray(); 29 char[] mchar = matchStr.toCharArray(); 30 int[] fixNum = lengthKMP(mchar); 31 System.out.println(Arrays.toString(fixNum)); 32 int neglect = 1; 33 for (int i = start; i <= searchchar.length - mchar.length; i += neglect) { 34 boolean con = true; 35 for (int j = 0; j < mchar.length; j++) { 36 if (searchchar[i + j] != mchar[j]) { 37 con = false; 38 neglect = j == 0 ? 1 : j - fixNum[j - 1]; 39 break; 40 } 41 } 42 if (con) { 43 return i + 1; 44 } 45 } 46 return -1; 47 } 48 49 /** 50 * 获取部分匹配值的共有元素的长度 <br> 51 * 52 * @param mchar 53 * @return 54 */ 55 public static int[] lengthKMP(char[] mchar) { 56 int[] fixNum = new int[mchar.length]; 57 for (int i = 1, j = 0; i < mchar.length; i++) { 58 if (mchar[j] == mchar[i]) { 59 fixNum[i] = j + 1; 60 j++; 61 } else if (j > 0) { 62 i -= j; 63 j = 0; 64 } 65 } 66 // return [0, 0, 0, 0, 1, 2, 0, 1, 2, 0]ABCDABDABD 67 return fixNum; 68 } 69 } 70 /* 71 * A BC 72 * AB C 73 * A BCD 74 * AB CD 75 * ABC D 76 * A BCDE 77 * AB CDE 78 * ABC DE 79 * ABCD E 80 */