KMP匹配算法

在说KMP匹配算法之前,我们先来看看与它相近的另一种匹配算法,名曰“暴力匹配算法”

1.暴力匹配算法(设有如下的两组字符串)

第一位不匹配,则向右移动一位,得到如下的形式


B与A依旧不匹配,则继续往后移,当移到如下的形式时:


尽管之前的文本串和模式串已经分别匹配到了S[9]、p[5].但因为S[10]和p[6]不匹配,所以文本串会回溯到p[0].从而让是s[5]跟p[0]匹配(S[5]与p[0]肯定匹配失败,因为S[5] = p[1] = B     P[0] = A.所以S[5] != P[0])得到如下结果:


然后又开始进行后移匹配。

这块的算法代码为:

if(S[i] == P[j])
{
    i++;
    j++;
}
else
{
    i = i-j+1;
    j = 0;
}

2.KMP匹配算法

相对于暴力匹配算法的改进是引入了一个跳转表nex[];

算法思路:

(1)假设现在文本串S匹配到i位置,模式串P匹配到j位置

(2)若j = -1,或者当前字符匹配成功(即S[i] == P[j])都令i++,j++继续匹配下一字符;

(3)若j != -1,且当前字符匹配失败(即S[i] != P[j]),则令i不变 j = next[j](当匹配失败时,模式串向右移动的位数为:失配字符所在的位置 - 失配字符所对应的nex值,即移动的实际位数为j - next[j](当前字符串中有多大长度的相同前缀后缀)),如下表:

模式串的单个子串 前缀 后缀 最大公共元素长度
A 0
AB A B 0
ABCD A,AB,ABC D,CD,BCD 0
ABCDA A,AB,ABC,ABCD A,DA,CDA,BCDA 1
ABCDAB A,AB,ABC,ABCD,ABCDA B,AB,DAB,CDAB,BCDAB(长度为2) 2
ABCDABD A,AB,ABC,ABCD,ABCDA,ABCDAB D,BD,ABD,DABD,CDABD,BCDABD 0

因此:


第一位都不匹配,直接将模式串不断向右移一位,直到模式串中的字符A和文本中的第5个字符A匹配成功


此时,匹配的字符数为6个,Next[j] = 2 ,j=6.所以:右移 j-Next[j] = 6-2 = 4个


Next[j] = 0       j = 2       所以:右移 2-0 = 2位


右移一位


然后继续右移4位


至此,文本串和字符串已经匹配成功

具体算法:

if(j == -1 || S[i] == P[j])
{
    i++;
    j++;
}
else
{
    j = Next[j];
}





   

猜你喜欢

转载自blog.csdn.net/m0_37962600/article/details/79941484