zoukankan      html  css  js  c++  java
  • KMP算法,这是我看到的最简单的最好理解的KMP算法

    看的文章来源于

    http://www.cnblogs.com/c-cloud/p/3224788.html

    好理解在求Next的方法(推荐看原文)

    Next实现

     1 void makeNext(const char P[],int next[])
     2 {
     3     int q,k;//q:模版字符串下标;k:最大前后缀长度
     4     int m = strlen(P);//模版字符串长度
     5     next[0] = 0;//模版字符串的第一个字符的最大前后缀长度为0
     6     for (q = 1,k = 0; q < m; ++q)//for循环,从第二个字符开始,依次计算每一个字符对应的next值
     7     {
     8         while(k > 0 && P[q] != P[k])//递归的求出P[0]···P[q]的最大的相同的前后缀长度k
     9             k = next[k-1];          //不理解没关系看下面的分析,这个while循环是整段代码的精髓所在,确实不好理解  
    10         if (P[q] == P[k])//如果相等,那么最大相同前后缀长度加1
    11         {
    12             k++;
    13         }
    14         next[q] = k;
    15     }
    16 }

    下面对原文中的重点在强调一次,并增加了自己的理解。

    现在我着重讲解一下while循环所做的工作:

    1.   已知前一步计算时最大相同的前后缀长度为k(k>0),即P[0]···P[k-1];
    2.   此时比较第k项P[k]与P[q],如图1所示
    3.   如果P[K]等于P[q],那么很简单跳出while循环;
    4.   关键!关键有木有!关键如果不等呢???那么我们应该利用已经得到的next[0]···next[k-1]来求P[0]···P[k-1]这个子串中最大相同前后缀,可能有同学要问了——为什么要求P[0]···P[k-1]的最大相同前后缀呢???是啊!为什么呢? 原因在于P[k]已经和P[q]失配了,而且P[q-k] ··· P[q-1]又与P[0] ···P[k-1]相同,看来P[0]···P[k-1]这么长的子串是用不了了,那么我要找个同样也是P[0]打头、P[k-1]结尾的子串即P[0]···P[j-1](j==next[k-1]),看看它的下一项P[j]是否能和P[q]匹配。如图2所示

    结合上边的图片  我增加一个自己的例子  

    0   1   2   3    4   5   6    7   8   9   10   11   12   13        模板下标 q

    A   B   C   D   A   B   D   A   B  C    D    A     B    C         字符串模板P

    0   0    0    0   1   2   0    1   2     3    4     5     6    3          next 记录

    注意最后一个  3   是怎么来的  P[ 13 ] !=  P[ 7 ] ( 图2 中的 P[ q ] != P[ k ] )   此时执行while   得到 k = next[ 7 - 1 ] = 2 此时 P[ 13 ] !=  P[ 2 ] 跳出while循环,然后执行if判断,得到 next[ 13 ] = 2 + 1

    反应到图2中,当不相等发生时,寻找前一个最大字串,即,寻找前一个最大K ( k = next[ 7 - 1 ] = 2)并判断是否可以拼接上( P[ 13 ] !=  P[ 2 ] )(相等就能拼接上)。

    话术蹩脚     凑合着看

    KMP实现

     1 #include<stdio.h>
     2 #include<string.h>
     3 void makeNext(const char P[],int next[])
     4 {
     5     int q,k;
     6     int m = strlen(P);
     7     next[0] = 0;
     8     for (q = 1,k = 0; q < m; ++q)
     9     {
    10         while(k > 0 && P[q] != P[k])
    11             k = next[k-1];
    12         if (P[q] == P[k])
    13         {
    14             k++;
    15         }
    16         next[q] = k;
    17     }
    18 }
    19 
    20 int kmp(const char T[],const char P[],int next[])
    21 {
    22     int n,m;
    23     int i,q;
    24     n = strlen(T);
    25     m = strlen(P);
    26     makeNext(P,next);
    27     for (i = 0,q = 0; i < n; ++i)
    28     {
    29         while(q > 0 && P[q] != T[i])
    30             q = next[q-1];
    31         if (P[q] == T[i])
    32         {
    33             q++;
    34         }
    35         if (q == m) // 输出找到的位置  还可以判断i == n - 1 未找到
    36         {
    37             printf("Pattern occurs with shift:%d
    ",(i-m+1));
    38         }
    39     }    
    40 }
    41 
    42 int main()
    43 {
    44     int i;
    45     int next[100]={0};
    46     char T[20], P[20];
    47     scanf("%s%s", T,P);
    48     
    49     printf("%s
    ",T);
    50     printf("%s
    ",P );
    51     // makeNext(P,next);
    52     kmp(T,P,next);
    53     for (i = 0; i < strlen(P); ++i)
    54     {
    55         printf("%d ",next[i]);
    56     }
    57     printf("
    ");
    58 
    59     return 0;
    60 }
  • 相关阅读:
    Changing Icon File Of Push Button At Runtime In Oracle Forms 6i
    Set Font Properties On Mouse Hover Of Push Button And Text Items At Run time In Oracle Forms
    Change An Item Property Using Set_Item_Property In Oracle Forms
    Calling / Running a report in Oracle forms 10g / 11g
    Change Or Set Report Object Property At Run Time In Oracle Forms Using Set_Report_Object_Property Command
    Refresh / Updating a form screen in Oracle D2k Forms 6i
    Know How And When To Use System.Message_Level To Control Messages In Oracle Forms
    Perform Cut Copy Paste Operations Using Cut_Region Copy_Region Paste_Region Commands In Oracle Forms
    CHECKBOX_CHECKED built-in in Oracle D2k Forms
    Limiting To Select Only 5 Check Boxes Out Of Ten In Oracle Forms
  • 原文地址:https://www.cnblogs.com/sn944/p/5933006.html
Copyright © 2011-2022 走看看