1 public class KpmStr {
2 public int getIndexOf(String s, String m) {
3 if (s == null || m == null || s.length() < 1 || m.length() < 1 || s.length() < m.length()) {
4 return -1;
5 }
6 char[] i = s.toCharArray();
7 char[] j = m.toCharArray();
8 int[] index = getIndex(j);
9 int k = 0;
10 int f = 0;
11 while (k < i.length && f < j.length) {
12 if (i[k] == j[f]) {
13 k++;
14 f++;
15 } else if (index[f] == -1) {
16 k++;
17 } else {
18 f = index[f];
19 }
20 }
21 return f == j.length ? k - f : -1;
22 }
23 // 求字符前面字符串中 前缀和后缀匹配的最大长度 不能取总长总长肯定一致无意义
24 private int[] getIndex(char[] m) {
25 if (m.length == 1) {
26 return new int[]{-1};
27 }
28 int[] res = new int[m.length];
29 res[0] = -1;
30 res[1] = 0;
31 int index = 2;
32 int cn = 0;
33 while (index < m.length) {
34 if (m[cn] == m[index - 1]) {
35 res[index++] = ++cn; // index-1位置的字符与 前一个位置下标cn位置字符相等 index位置的值 等于cn+1
36 // index进行下一个字符的比对 cn已经加一的++cn是为了方便计算
37 } else if (cn > 0) {
38 // 字符不匹配 跳到cn位置的字符比较
39 cn = res[cn];
40 } else {
41 // cn到m[]的头了
42 res[index++] = 0;
43 }
44 }
45 return res;
46 }
47 }