KMP算法

Posted hoyoak

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了KMP算法相关的知识,希望对你有一定的参考价值。

KMP算法是一种高效的字符串匹配算法。

KMP算法的特点是给定一个主串,给定一个匹配串,问匹配串在主串中出现的次数,匹配串在主串中出现的位置等。

首先我们先看一种暴力的方法——按位对比,若匹配失败从头再来。

我们用两个指针,一个指针i指在主串,一个指针j指在匹配串,

如果s1[i+1]!=s2[j+1],根据暴力的思想就从头开始匹配,i=匹配开头+1,j=1;

显然这么不优,这样太过暴力,KMP算法的核心思想就是对于匹配失败后j的位置做一个优化。

我们来看下面这种情况

s1=‘aabaac‘ s2=‘aabaabaac‘

当i=j=5的时候 显然s[i+1]!=s[j+1];

技术图片

 

 

 若是按照原来暴力的想法此时应把匹配串的j调整为1,i调整为匹配开头+1;

但我们发现匹配串有个性质就是部分回文,s1的前五个元素为aabaa,此时如果把i++,j=3便可继续匹配。

利用这个性质,我们可以对原方法有一个很大的优化即——KMP算法。

KMP的核心是预处理一个fail数组即确定匹配失败后,j指针应该调整到哪个位置。

预处理的方法就是自我匹配,显然fail[1]=0;

 

1 int s2_len=strlen(s2+1);
2 int j=1;
3 for(int i=1;i<=s2_len;i++)
4 
5     while(s[i]!=s[j+1]&&j>0) j=fail[j];
6     if(s[i]==s[j+1]) j++;
7     fail[i]=j;
8 

 

然后匹配匹配串与主串即可。

全部代码洛谷P3375

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 
 8 int kmp[1000005],n,m;
 9 char s1[1000005],s2[1000005];
10 
11 int main()
12 
13     scanf("%s%s",s1+1,s2+1);
14     n=strlen(s1+1);
15     m=strlen(s2+1);
16     kmp[1]=0;
17     int j=0;
18     for(int i=2;i<=m;i++)
19     
20         while(j&&s2[j+1]!=s2[i]) j=kmp[j];
21         if(s2[j+1]==s2[i]) j++;
22         kmp[i]=j;
23     
24     j=0;
25     for(int i=1;i<=n;i++)
26     
27         while(j&&s1[i]!=s2[j+1]) j=kmp[j];
28         if(s2[j+1]==s1[i]) j++;
29         if(j==m)
30         
31             printf("%d\\n",i-m+1);
32             j=kmp[j];
33         
34     
35     for(int i=1;i<=m;i++)
36        printf("%d ",kmp[i]);
37     return 0; 
38 

 

以上是关于KMP算法的主要内容,如果未能解决你的问题,请参考以下文章

什么是KMP算法?KMP算法推导

KMP算法及KMP算法的应用(POJ2406)

KMP算法

kmp算法

kmp算法

KMP算法