我今天才真正的看懂了,串模式匹配算法KMP,我以前学过但是没有深入的理解。今天我让自己理解了,
其实说到底要特别注意KMP算法和其中的NEXT值的求法是一个递推的过程,首先来看看最简单的匹配算法的形式。
int index(HString s, HString T, int pos)
{
int i=pos; int j=1;
while(i<=s.length()&&j<T.length())
{ if(s.ch[i]==T.ch[j])
++i; ++j;
else{
j=i-j+2;// 这是当指针i与j的字符串不配时要退回从模式串的第一个数又开始一次的匹配。
}
return i-T.length();
}
从这个简单的匹配来看,很容易理解。只要记得当指针所指的模式串与原串不匹配时要记得退回指针一个个的
匹配。这样从算法的分析来看这个算法的o(T)的最坏时间到了M*N的级别。所以要想到的问题怎么使这个原串的的指针不在退回去,直接往前移。这个时候算法大师想出了一种采用标记模式串的方式来解决指针回嗍的问题。也就是NEXT函数的问题。
其实KMP算法着重就在于理解这个next函数值使怎么样标记的。首先我们来next。其实它就是一个标记器。所以它用数组来表示。首先我们来看这个函数。
void GetNext(HString S,HString T,int next[])
{
next[1]=0;// 这个是规定。主要的作用要理解它是做什么的。
int i=1,j=0;
while(i<=S.length()&&j<=T.length())
{
if(j==0||S.ch[i]==T.ch[j])
{ ++i; ++j, next[i]=j; } 这一句就是做标记了,
else j=next[j];//那为什么不等的时候要j的值要回到next[j]去呢?
}
}
我前面说了要理解这个还要理解它是一个递推的过程。next[1]=0就是给它构造的原始的值。以至能构成递推的形式来标记next[i]的值。
首先来看是怎么递推的。
例。
123456789 i的位置。
ababcabac //模式串。这里的指针标记是i;
ababcabac //模式串。设这是的指针标记是j
我们用模式串跟自己来比。从函数来看由于开始j=0。然后++i,+j;所以从i=2.j=1开始。因为第一个不用比了肯定是一样的。
则有。