正在学习数据结构,刚开始接触KMP算法,真的懵...看了许多许多文章,再加上课上的讲解和自己的理解,总算有点懂了。记录一下,便于日后复习。

  话不多说,进入正题:

  先附上琢磨许久的代码,也就是两个getnext函数

   getnext_1是正常的循环思路,getnext_2是比较巧妙的思路,其实本质上是一致的。

  

 1 void getnext_1(char T[],int next[]){//利用next[0];双层循环
 2     int i=0,j=-1;
 3     next[0]=-1;
 4     for(;i<strlen(T);i++){
 5         while(j>=0&&T[i]!=T[j]){
 6             j=next[j];
 7         }
 8         /* 1.j=-1,找到头也始终找不到符合条件 ;2.j>0,T[i]=T[j],找到了 */
 9         j++;
10         next[i+1]=j;//外层用的是for,会自行累加i;这里i+1存入next,i在外层for循环中+1,后再进行后续比较寻找操作,求下个i值,又是一层循环
11     }
12 }
13 
14 
15 void getnext_2(char T[],int next[]){//利用next[0];单层循环,教材方法  递推思想
16     int i=0;
17     next[0]=-1;
18     int j=-1;
19     while(i<strlen(T)){//每次进行该判断时,next[i]=j,对应关系,再进行下去,对T[i]、T[j]比较,从而得出i+1的值
20         if(j==-1||T[i]==T[j]){
21             /* 1.j=-1,找到头也始终找不到符合条件 ;2.j>0,T[i]=T[j],找到了 */
22             i++;//循环:将i+1赋值,并循环下去
23             j++;
24             next[i]=j;//存储值,并作为找下个next的先判断条件
25         }
26         else j=next[j];//j!=0 T[i]!=T[j] j向前找;循环,向前找j,直至符合,找到j=-1,已经找到头了。
27     }
28 }
Here!Here!Point this,know more......

 

  大多数据结构中,KMP算法是在讲解串的结构引入的,串的存储形式又是有分 定长顺序存储结构 和 堆分配存储结构 。

-------------(重点)----------------

  实现KMP算法时,用的语言会造成不同理解错觉。

       举例C/C++,串,可以以字符串的形式完成,但下标0是存储元素的,尾号下标存“\0”。大多讲解KMP,使用定长顺序存储结构,以类C语言写出来,下标0村的是串长。

  为了方便理解,next数组和字符串位置是对应关系。下标还是位序(从1开始)?极其令人误解!!

  

  主要求next的思想方法:

        由于其中具体比较过程复杂,同时又要进行循环,实现每个字符对应的next值,这里给的循环思想跟以往不太相同:比较、操作,最后得出值,再在i++上赋值,具体见代码。主要用了递推的方法,从next[0]...依次推下去,类似于数学归纳法和数列。

 

  本文并没有细讲KMP,网上有很多,这里只是讲了一些本人觉得难以理解的地方。

  补充主函数:

  

 1 int main()
 2 {
 3     int i;
 4     char *P="xygxygd";//"abaabcac";
 5     int *next = new int[strlen(P)];
 6     /*
 7     getnext_2(P,next);
 8     for(i=0;i<strlen(P);i++)
 9         cout<<next[i];
10     cout<<endl;
11     */
12     getnext_1(P,next);
13     for(i=0;i<strlen(P);i++)
14         cout<<next[i];
15     cout<<endl;
View Code

 

  本人还推荐一种理解方法:画图:

   下标/i 0 1 2 3 4 5 6 7 8
  T a b a a b c a c  
  next[]/j  -1 0 0 1 1 2 0 1  
nextval[]                  

  j=-1,i++,j++进行下个循环

  判断T[i]、T[j]是否相等?相等:匹配成功,i++,j++,进行下一个循环;不相等:j=next[j],进入最优的最近的重新匹配对象,借助前面已经匹配的数据,在比较。

 

 nextval[],BF算法,KMP算法的实现日后再见