关于KMP算法,自己给出了一些讲解,写的不太好,见谅!
原理:
举例,给出文本串和模式串,判断文本串中是否包含模式串
原理是找到最长相等的前后缀
这里要用到前缀表,涉及到前缀和后缀的概念。
前缀:包含首字母,不包含尾字母的所有子串
对于模式串,它的前缀是:
a |
---|
aa |
aab |
aaba |
aabaa |
后缀:包含尾字母不包含首字母的所有子串
模式串的后缀是:
f |
---|
af |
aaf |
baaf |
abaaf |
前缀表就是:
a (子串) | 0 (表示相等前后缀的数量) |
---|---|
aa | 1 |
aab | 0 |
aaba | 1 |
aabaa | 2 |
aabaaf | 0 |
过程:找前面子串的最长相等前后缀。 很显然,最长相等前后缀是2,会跳到下标为2处,也就是b,从b开始重新匹配(这也是前缀表的特性)。
解释:寻找最长相等前后缀的长度意味着这里有一个后缀aa, 前面也有一个与其相等的前缀aa,我们在这个后缀的后面发生不匹配了,我们就要找与其相等的前缀的后面也就是 b 开始匹配。最长相等前后缀是2,那前缀的后面 b 的下标就正好是前缀的长度,因为索引是从0开始的。
代码实现:
用next数组表示前缀表,next数组的核心:遇见冲突,向前回退。
next数组表示如图所示:
如何得到next数组,代码如下,感兴趣可以自行研究一下:
void getNext( String s){
//i表示后缀末尾,j表示前缀末尾
int j=0;
int i;
int next[0];
for(i=1;i<s.length();i++) i++;
char[] ch = s.toCharArray();
while (j>0&&ch[i]!=ch[j]) j=next[j-1];
if(ch[i]==ch[j]) j++;
next[i]=j;
}