在KMP算法中有个数组,叫做前缀数组,也有的叫next数组,每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符,当然它描述的也是子串的对称程度,程度越高,值越大,当然之前可能出现再匹配的机会就更大。
这个next数组的求法是KMP算法的关键,但不是很好理解,我在这里用通俗的话解释一下,看到别的地方到处是数学公式推导,看得都蛋疼,这个篇文章仅贡献给不喜欢看数学公式又想理解KMP算法的同学。
主要是求解next数组,而求next数组又离不开一个概念 前缀后缀最长公共元素长度
比如下图:
理解了这概念,就看如何求解这个数组,我这里没用教材里面方法,而是根据简单的思路先求出prefix数组,
然后把prefix数组右移一位得到next数组。
Java代码如下:
public static void getNext(String p,int[] prefix,int[] next){
//prefix[i]表示 【0,i】中前缀后缀最长公共元素长度
int len=p.length();
for(int i=1;i<len;i++){
int k=prefix[i-1];//每次根据prefix[i-1]来求解prefix[i],默认prefix[0]=0;
while(p.charAt(i)!=p.charAt(k)&&k!=0){
k=prefix[k-1];//不断递归判断是否存在子对称,k=0说明不再有子对称.
}
if(p.charAt(i)==p.charAt(k))
prefix[i]=k+1;//找到了这个子对称,或者是直接继承了前面的对称性,这两种都在前面的基础上++
else
prefix[i]=0;//如果遍历了所有子对称都无效,说明这个新字符不具有对称性,清0
}
next[0]=-1;
for(int i=1;i<next.length;i++){
next[i]=prefix[i-1];
}
}
、
简单的测试如下:
大体的思路就是这样,基于这个思路可以得到更多的优化,具体的详细解释以及优化方案可以看大佬们的文章。
reference:https://blog.csdn.net/gao506440410/article/details/81812163
https://blog.csdn.net/yearn520/article/details/6729426