zoukankan      html  css  js  c++  java
  • KMP算法的next[]

      正在学习数据结构,刚开始接触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是存储元素的,尾号下标存“”。大多讲解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算法的实现日后再见

  • 相关阅读:
    在Struts 2.0中实现表单数据校验(Validation)
    在Struts 2中实现IoC
    Atcoder Grand Contest 038 E Gachapon(MinMax 容斥+背包)
    快速沃尔什变换&快速莫比乌斯变换小记
    HDU1495 非常可乐 (嵌套结构体广搜 对比 一般广搜)
    【胡搞的不能AC的题解,暴力搜索一发博弈问题】1995 三子棋 51Nod
    【Low版】HAUT OJ Contest1035 2017届新生周赛(六)题解
    【动态规划】ZZNUOJ 2054 : 油田
    实验报告——直接插入排序、改进的冒泡排序和归并排序实现整数数组的排序
    【万能的搜索,用广搜来解决DP问题】ZZNU 2046 : 生化危机 / HDU 1260:Tickets
  • 原文地址:https://www.cnblogs.com/wssblogs/p/7692300.html
Copyright © 2011-2022 走看看