算法入门之KMP

来源:互联网 发布:mac虚拟机内存分配 编辑:程序博客网 时间:2024/04/28 03:39

KMP入门:

KMP算法是一种改进的字符串匹配算法,是D.E.Knuth与V.R.Pratt和J.H.Morris同时发现的算法。

比一般算法添加一个next[]数组。

next[]数组函数,通过子串自身匹配,找到指针的回溯,而主串不回溯的原理。使时间复杂度变为线性

查找。O(n+m);

next[j]的表达式为:1.next[j]=0;2.next[j]=-1;3.next[j]=max(k|0<k<j,且"t0t1...tk-1"="tj-ktj-k+1...tj-1";

由此为模:http://acm.hdu.edu.cn/showproblem.php?pid=1711

KMP算法技巧:

1.定义各个数组。

const int maxm=10010;const int maxn=1000010;int str[maxn];int keyword[maxm];int next[maxm];int n,m;
2.构造next[]函数。

1).初值next[0]=-1;

2).若字符串匹配,或者k==-1.a.条件满足,进行3).否则将子段指向k=next[k].

next[k],即是前面字符的next[]值,表示是字段的回溯值。

3).当字符串不匹配时,next[j]=k;否则next[j]=next[k],表示的是:前面所出现

相同字符标号次数。

4).next[]值通过当前匹配推下个next[]值,并通过k的next[]值达到字段回溯,达到一种手段。

如{abcdaabcab}next[]值,优化前next={-1,0,0,0,0,1,1,2,3,1},优化后={-1,0,0,0,-1,1,0,0,3,0}。

void get_next(){    int j,k;    j=0;    k=-1;    next[0]=-1;    while(j<m)    {        if(k==-1||keyword[j]==keyword[k]){           j++;   k++;   if(keyword[j]!=keyword[k])             next[j]=k;   else   next[j]=next[k];        }        elsek=next[k];    }    } 

3.KMP算法,运用next[].不断字段回溯找相同字串。

int KMP_index(){    int i=0,j=0;int p;    get_next();    while(i<n&&j<m)    {        if(j==-1||str[i]==keyword[j])        {            i++;            j++;        }            elsej=next[j];            }        if(j>=m) p=i-m+1;    else p=-1;return p;}      
5.函数main()。

int main(){    int i,j,T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&m);        for(i=0;i<n;i++)          scanf("%d",&str[i]);        for(i=0;i<m;i++)          scanf("%d",&keyword[i]);        printf("%d\n",KMP_index());    }        return 0;}    
6.总结。KMP入门,理解不是很好。


原创粉丝点击