码迷,mamicode.com
首页 > 编程语言 > 详细

KMP算法

时间:2015-04-18 08:51:37      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:

在简单的模式匹配时,每次遇到s[i]!=t[j] 时,每次都要讲i回溯。这往往浪费了很多时间。KMP算法就是当遇到s[i]!=t[j] 时,只让t[j] 回溯而s[i]不用回溯,这样就节省了很多时间。

当t[1]t[2]…t[j-1]=s[i-j+1]s[2]…s[i-1]成立时,若t[j]!=s[i],则此时根据KMP算法只用回溯t[j].
假设有k( k< j)使t[1]t[2]…t[k-1]=s[i-k+1]s[i-k+2]…s[i-1]
可见若有k则不用让t从1开始匹配了,从k开始匹配就行了。可见主要就是求k的值。
因为 t[1]t[2]…t[j-1]=s[i-j+1]s[i-j+2]…s[i-1]
因为k将t[1]t[2]…t[j-1]分成了两部分。因为成立,可知 t[j-k+1]t[j-k+2]…t[j-1]=s[i-k+1]s[i-k+2]…s[i-1] ;
由得。t[1]t[2]…t[k-1]=t[j-k+1]t[j-k+2]…t[j-1]。所以k的值满足这个等式。由这个等式就可以得到k的值。
记字符串t中t[j]的k值为next[j];
下面就是求next[j]:
当j=1时 next[1]=0.
当有k满足t[1]t[2]…t[k-1]=t[j-k+1]t[j-k+2]…t[j-1]时。next[j]=k,当再往右移动一个元素时,当t[k]=t[j]时t[1]t[2]…t[k-1]t[k]=t[j-k+1]t[j-k+2]…t[j-1]t[j].此时next[j+1]=k+1=next[j]+1.
当t[k]!=t[j]时,此时,就应当求出一个k1值使t[1]t[2]…t[k1-1]t[k1]=t[j-k1+1]t[j-k1+2]…t[j-1]t[j]成立。此时已经有t[1]t[2]…t[k-1]=t[j-k+1]t[j-k+2]…t[j-1]成立,所以要想将前一个等式成立的话,就相当于模式匹配了(字符串t即相当于主串又相当于模式)。所k1=next[k],且
t[k1]=t[j].则说明在主串中第j+1个字符之前存在一个最大长度的k1的子串t[1]t[2]…t[k1-1]t[k1]=t[j-k1+1]t[j-k1+2]…t[j-1]t[j].
因此这时候next[j+1]=k1+1=next[k]+1。
若t[k1]!=t[j]则继续往后推。k2=next[k1]=next[next[k]].若k2满足t[1]t[2]…t[k2-1]t[k2]=t[j-k2+1]t[j-k2+2]…t[j-1]t[j]. 则next[j+1]=k2+1=next[next[k]]。
如果不符合就继续往下推导。直到tj和模式中的某个字符匹配成功或者不存在任何ki满足
t[1]t[2]…t[ki-1]t[ki]=t[j-ki+1]t[j-ki+2]…t[j-1]t[j]. 则有next[j+1]=1.

下面就是求next的函数

void Count_next(char *t,int next[])
{
    int i,j;
    i=1;j=0;
    next[i]=0;
    while(i<t[0]){
        if(j==0){j++;i++;next[i]=1;}
        else if(t[j]==t[i]){j++;i++;next[i]=j;}
        else if(t[j]!=t[i])j=next[j];
    }
}

程序解析:程序中i的值就是遍历整个字符串,j的值就是记录每个next[i]。如果t[i]!=t[j]则++j,就是next[i]=next[i-1]+1;若不满足t[i]!=t[j]则j=next[j],就是使j回溯。
下面就是利用KMP算法实现模式匹配了。

int pattern(char *s,char *t,int next[])
{
    int i=1,j=1;
    while(i<=s[0]&&j<=t[0]){//如果相等就往后推移
        if(j==0||s[i]==t[j]){i++;j++;}
        else j=next[j];
    }
    if(j>t[0])
        return i-t[0];//返回模式在主串中的起始位置
    else
        return -1;
}

KMP算法

标签:

原文地址:http://blog.csdn.net/u014104588/article/details/45102955

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!