s1mplesama

导航

KMP算法的代码实现

 

以下代码为第一步求最大前后缀所含字符个数的代码:

首先我们明确:next[i]存放的是前i个字符组成的字符串的最大相同前后缀长度

 1     public static int[] kmpnext(String str){              //参数为要求的字符串str
 2         int[] next = new int[str.length()];               //新建一个next数组,每一位存放对应的前n位组成的子字符串的最大前后缀相同元素个数
 3         next[0] = 0;                             //第一位没有前后缀,故为0
 4         for(int i = 1,j = 0; i < str.length(); i++){          //从第二位开始,依次求出所求的值
 5             while(j > 0 && str.charAt(j) != str.charAt(i)){     //重要,下面详细解释此处
 6                 j = next[j - 1];
 7             }
 8             if(str.charAt(i) == str.charAt(j)){             //上一轮循环已经比较过了前j位与后j位相同,此时若第j+1位,即索引位j的值与索引为i的值相同,那么在这一轮循环中,新字符串的最大前后缀就是上一轮的+1
 9                 j++;
10             }
11             next[i] = j;                           //将所求的值j存放到对应位置
12         }
13         return next;
14     }

 

while(j>0 && str.charAt(j) != str.charAt(i))的意思是:

  此时j的值为上一轮循环当中存放在next[i]中的值,即上一轮循环中前i位的最大前后缀的值,

  此时循环+1,即比较新增加的一位与前缀中新增加的一位是否相等,相等的话执行j++

  不等的话执行j=next[j-1];

 

j=next[j-1]是这段代码中最难理解的部分,下面为解释:

 

  

  此时发现charAt(j) != cjarAt(i),我们将目光放在索引为j之前的子字符串中:

  改变了j的值后,图示的两块橘色矩形为相同序列,

  我们再比较新位置上的charAt(j)与charAt(i)是否相等即可,如果不相等则利用j=next[j-1]继续缩小j的值。

 

 




posted on 2018-12-02 05:51  s1mplesama  阅读(2730)  评论(0编辑  收藏  举报