KMP算法是字符串匹配的算法,传统的字符串暴力匹配效率之所以不高的原因,在于对于原串来说,每次匹配失败之后,都要将其指针回溯到最初匹配成功的第一个字符的位置。
那么可以不让原串指针回溯吗?答:完全可以,kmp算法就是为了解决这种指针回溯问题。
/** 字符串匹配算法 */ class Kmp { static int match(String s, String pattern) { //根据模式串获取其next数组,next数组第一位默认为-1,其后的每位都对应着其子串中前缀和后缀的最大公共连续子串的长度 int[] next = next(pattern); int len = s.length(); int i = 0; int j = 0; //匹配结束的条件是s或者p都匹配到了末尾 while (i < len && j < next.length) { if (j == -1 || s.charAt(i) == pattern.charAt(j)) { i++; j++; } else { j = next[j]; } } //匹配结束之后,如果j==next.length,说明模式串的每一位都匹配成功了。 if (j == next.length) { return i - j; } //否则就是匹配失败了,返回-1 return -1; } static int[] next(String s) { char[] value = s.toCharArray(); int len = value.length; int[] next = new int[len]; next[0] = -1;//next的第0位默认为-1,类似哨兵 int i = -1;//字符串前缀指针 int j = 0;//后缀指针 while (j < len - 1) { //前缀和后缀匹配成功,则继续向后匹配 if (i == -1 || value[i] == value[j]) { ++i; ++j; next[j] = i; } else { i = next[i]; } } return next; } }