KMP算法

今天上数据结构的时候,老师讲了一下KMP,之前也接触过,记一下KMP的思想。参考了一些博客,等一下附上。

匹配两个字符串的时候,每次当失配的时候,都移动F串一位。所以时间复杂度是O(n*m);

但是当我匹配到I的时候,我忽略了前面的都已经匹配好了这个事实,利用起来。多移动一些K,K有什么特点呢?

例如:

直接要跳到最后一步。

这时:模式串每一个字符都记录这个失配指针,直接跳到这里,那么KMP很好写了。

void find(char *T,char *P,int *f)
{
    int n = strlen(T);
    int m = strlen(P);
    getFail(P,f);
    /*
    for(int i=0;i<m;i++)
        printf("%d ",f[i]);
    puts("");
    */

    int j = 0;
    for(int i=0; i<n; i++)
    {
        while(j&&P[j]!=T[i])
            j = f[j];
        if(P[j]==T[i]) j++;
        if(j==m) printf("%d
",i-m+1);
    }
}

那么,怎么得到next数组这个失配指针呢?

重点来了,就是模式串自己匹配自己。

根据f[0],f[1],...,f[i-1] 推 f[i];

void getFail(char *P,int *f)
{
    int m = strlen(P);
    f[0] = 0;
    f[1] = 0;
    for(int i=1; i<m; i++)
    {
        int j = f[i];
        while(j&&P[i]!=P[j])
            j = f[j];
        if(P[i]==P[j])
            f[i+1] = j+1;
        else f[i+1] = 0;
    }
}

f[0] = 0,f[1] = 0;

开始推f[2] ,也就是要匹配P[0],和P[1],匹配好了就是等于1,否则是0,

再往后走,就是类似之前的两个字符串的匹配了,不相等的时候就直接跳到  f[j] 进行匹配,直到匹配好。

参考:http://blog.csdn.net/yutianzuijin/article/details/11954939/

原文地址:https://www.cnblogs.com/TreeDream/p/5947184.html