您的位置:首页 > 其它

模式匹配之KMP算法的理解(二)

2008-12-17 10:17 309 查看
昨天说到了有公式"p1p2.......p(k-1)"=“p(j-k+1)p(j-k+2).......p(j-1)”.观察下该公式,这个等式是在模式串中存在的。很显然接下来的工作主要就是在模式串中找到这样的等式。模式串P中的pj(即模式串中的第j个字符)与主串中的Si不匹配的时候,将比较Si与模式串P中第k个pk字符比较。定义一个数组next[0......j-1].这个数组的值next[j-1]=k表示模式串P中第j个字符的与主串字符Si不匹配时应该将模式串移动的位置pk与Si继续比较。
根据这么分析的话,就可以得出KMP的算法如下:
typedef struct
{
char ch[MaxSize];
int len; //串长
}SqString;

int KMPIndex(SqString s,SqString t)
{
int next[MaxSize],i = 0 , j = 0, m;
GetNext(t,next); //获取next数组

while(i < s.len&& j < t.len)
{
if(j == -1 || s.ch[i] == t.ch[j])
{
i++;
j++;
}
else
j = next[j];
}
if(j >=t.len)
m = i-t.len;
else
m =-1;
return m;
}

下面说明next数组过程,next的定义如下:

next[j]= max{k|0<k<j,且"p1p2.......p(k-1)"=“p(j-k+1)p(j-k+2).......p(j-1)"} 此集合非空时
= -1 当 j = 0 时
= 0 其他情况

根据该定义 依次求next[j]的值。
定义next[0] =-1
next[j] = k;根据next[j] =k可以得出p1p2.......p(k-1)"=“p(j-k+1)p(j-k+2).......p(j-1),那么现在计算next[j+1].当pk=pj时,则有next[j+1] = k +1 =next[j]+1;而当pk!=pj时,p1p2.......p(k-1)pk"!=“p(j-k+1)p(j-k+2).......p(j-1)pj。那么此时pk不匹配。则应该移动到next[k]处。如果继续不匹配,则直至next[k] = 0
next数组的求法如下:
void GetNext(SqString t, int next[])
{
int j,k;
j =0 ;
k= -1 ;
next[0] =-1;
while(j < t.len -1)
{
if(k == -1||t.ch[j] == t.ch[k])
{
j++;
k++;
next[j] = k;
}
else
k =next [k];
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: