kmp algorithm study and pass a reference test (to check back often)

  Before the codeforces KMP made a similar topic, but not before a good grasp, and now basically forget, did not able to answer. Here is a little summary of the KMP algorithm.

  First, KMP algorithm is the core of the paper in the matching process, using the prefix and suffix string pattern matching to speed up the process, which is in their own experiments can be found. Secondly, when the array of core Next KMP algorithm, next [j] = k means that for mode string [0 ... j-1] bit, the presence of the maximum length of the prefix and suffix k is the same, it is noted that for purposes of kmp the case is next = [j] j can not occur. The calculation method next array I think the essence or DP, but the state transition process has used the idea of ​​recursion, thus making the algorithm becomes complicated.

  Here is the next variant array of questions on codeforces: http://codeforces.com/contest/1200/problem/E

  Thought next need to use an array, constructed to be combined in the form of two strings "S2 + S1", where the "+" match can be prevented bounds, further to be noted that the minimum lengths are constructed so as to reduce the time S1.S2 time the complexity. Finally Next [] to obtain the length of the last one combined portion.

  Here is his more accustomed to using for writing next cycle is complete array build.

 #include <stdio.h>
 
char ch[1000010];
int next[1000010];
 
char* mmerge(char* ch1,char* ch2,int &len1,int len2)
{
   //printf("%d %d ",len1,len2);
    int len=len1;if (len2<len) len=len2;
 
    for (int i=0;i<len;i++)
        ch[i]=ch2[i];
    ch[len]='+';
    for (int i=len*2,j=len1-1;i>len;i--,j--)
        ch[i]=ch1[j];
    ch[len*2+1]=0;
   // printf("%s\n",ch);
 
    next[0]=0;
    for (int i=1;i<=len*2;i++)
    {
        int j=next[i-1];
        while (j && ch[i]!=ch[j])
            j=next[j-1];
        if ( ch[i]==ch[j] ) next[i]=j+1;
        else next[i]=0;
    }
 
    //printf(" %d ",next[len*2]);
    for(int i=next[len*2];ch2[i];i++,len1++ )
        ch1[len1]=ch2[i];
    ch1[len1]=0;
 
    //printf("%s\n\n",ch1);
    return ch1;
}
 
int main()
{
    char ch1[1000010];
    int n;scanf("%d",&n);
    scanf("%s",ch1);
    int len1=0;
    while (ch1[len1]) len1++;
    for(int i=1;i<n;i++)
    {
        char ch2[1000010];
        scanf("%s",ch2);
        int len2=0;while (ch2[len2]) len2++;
        mmerge(ch1,ch2,len1,len2);
    }
    printf("%s",ch1);
}
View Code

  There are also written in normal use while loop (it may not be standard)

#include <stdio.h>

char ch[1000010];
int next[1000010];

char* mmerge(char* ch1,char* ch2,int &len1,int len2)
{
    
    int len=len1;if (len2<len) len=len2;

    for (int i=0;i<len;i++)
        ch[i]=ch2[i];
    ch[len]='+';
    for (int i=len*2,j=len1-1;i>len;i--,j--)
        ch[i]=ch1[j];
    ch[len*2+1]=0;


    next[0]=0;
    int now=1,mlen=0;
    while (now<=len*2)
    {
        if (ch[now]==ch[mlen])
        {
            next[now]=mlen+1;
            now++;mlen++;
        }
        else
        if (mlen==0)
            next[now++]=0;
        else
            mlen = next[mlen-1];
    }

    for(int i=next[len*2];ch2[i];i++,len1++ )
        ch1[len1]=ch2[i];
    ch1[len1]=0;

    return ch1;
}

int main()
{
    char ch1[1000010];
    int n;scanf("%d",&n);
    scanf("%s",ch1);
    int len1=0;
    while (ch1[len1]) len1++;
    for(int i=1;i<n;i++)
    {
        char ch2[1000010];
        scanf("%s",ch2);
        int len2=0;while (ch2[len2]) len2++;
        mmerge(ch1,ch2,len1,len2);
    }
    printf("%s",ch1);
}
View Code

  In the program, but also a bold attempt to pass an object pointer did not dare use and the use of references & finish pass values ​​and hopes to use some more this programmatically, in favor of engineering practice. Also beginning with the next ch array of arrays placed in mmerge function, it appears to be a stack overflow problem (need to focus on the future, not quite understand).

  Then do a normal KMP example, http://acm.hdu.edu.cn/showproblem.php?pid=1686 , ask S1 S2 appeared many times in the string?

#include <stdio.h>

int ans( char* S, char* P, int* next )
{
    int aans=0;
    int len1=0;while (S[len1]) len1++;
    int len2=0;while (P[len2]) len2++;
    next[0]=-1;
    int now=0,mlen=-1;
    while (now<len1)
    {
        if (mlen==-1 || S[now]==S[mlen] )
        {
            mlen++;
            now++;
            next[now]=mlen;
        }
        else
            mlen=next[mlen];
    }

    int i=0,j=0;
    while (j<len2)
    {
        if (i==len1) aans++,i=next[i];
        if (i==-1 || S[i]==P[j])
            i++,j++;
        else
            i=next[i];

    }
    if (i==len1) aans++;
    return aans;

}

int main()
{
    int T;scanf("%d",&T);
    while (T--)
    {
        char ch1[10010];
        char ch2[1000010];
        scanf("%s%s",ch1,ch2);
        int next[10010];
        printf("%d\n", ans(ch1,ch2,next) );
    }
}
View Code

  For KMP, the current understanding of the principles, and he is able to write the code, but the feeling is not enough skilled, often come back to see it :)

Guess you like

Origin www.cnblogs.com/askl123/p/11423227.html