KMP算法理解

来源:互联网 发布:编程需要什么样的cpu 编辑:程序博客网 时间:2024/06/16 04:16

KMP算法是对普通模式匹配算法的一种改进算法,这种改进算法是D.E.Knuth与V.R.Pratt和J.H.Morris同时发现的,因此人们称它为KMP算法。

KMP算法最大的特征就是引进了跳转表(next表),下面我们来说说KMP算法与普通算法的区别。

这里我们先提一个已知条件:目标串(target)中某一个子串与模式串(pattern)的前i个字符相匹配时

(即target[m……m+(i-1)]与pattern[1……i]相匹配)。若发生target[m+i]与pattern[i+1]不匹配,我们来看看普通算法跟KMP算法的不同。

普通算法:将pattern[1]与target[m+i]对齐,然后逐一匹配。

KMP算法:将模式串后移 i+1-next[i+1] 个字符,使pattern[next[i+1]]与target[m+i]对齐,然后依次向后匹配。

看到这里我们大概知道next表归根结底解决的是一个前缀包含问题,而KMP算法的核心就在于next表。

我们假设模式串pattern = 'p1p2……pn',在这里我们引入一个概念f(j)。f(j):所有使'p1……pk-1' = 'pj-(k-1)……pj-1'成立的k的最大值。

这个概念一定要理解透彻。

我们回到上方的已知条件,当pattern[i+1]与target[m+i]进行匹配时,若匹配成功则依次向后继续匹配,若不成功,则要找到使上式成立的f(j),也就是k的最大值,然后从第k个字符开始与target[m+i]匹配,也就是说模式串中与target[m+i]匹配的字符从pattern[i+1]跳转到了

pattern[k](即将模式串向后移 i+1-next[i+1]),这里的跳转用到了next表,即 next[i+1] = k。

next函数值的算法如下:

void get_next(SString T, int next[])

{

int i = 1;

int j = 0;

next[1] = 0;

while(i < T[0])

{

if( j == 0 || T[i] == T[j])

{

++i;

++j;

next[i] = j;

}

else

j = next[j];

}

}

原创粉丝点击