KMP算法
程序员文章站
2022-05-02 17:44:13
...
发布文章 博文管理我的博客退出 Trash Temp KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 KMP算法 ## 浅谈KMP算法
① 寻找next(有的地方是F数组)数组
例如:T(长串) P(短串)
Index: 0 1 2 3 4 5 6 7 8 9
T: A B A B A B A B C A ( 1 )
P: 0 0 1 2 3 4 5 6 0 1 ( 2 )
next: -1 0 0 1 2 3 4 5 6 0 1
( 1 ) . 寻找前缀后缀最长公共长度;
( 2 ) . 求next数组;
next数组考虑的是除当前字符外的最长相同牵住后缀,所以通过 ( 1 ) 求得各个前缀后缀的公共元素的最大长度后,只要稍作变形即可:
将第一步中求得的值整体后移一位,然后初值赋为-1;
②求next数组代码
void Getnext()
{
int i=0;
int j=-1;
int p=strlen(P);
next[0]=-1;
while (i<p)
{
if (j==-1 || P[i]==P[j])
{
i++;
j++;
next[i]=j;
}
else
{
j=next[j];
}
}
}
例题:已知字符串T,P,求P在T中出现的次数(可以重叠)
input :ZYZYZYZ
output:3
代码实现:
#include<stdio.h>
#include<string.h>
using namespace std;
const int N=1e6+5;
char T[N],P[N];
int next[N];
int cnt;void find();
void Getnext();
int main()
{
scanf("%s %s",T,P);
find();
printf("%d\n",cnt);
return 0;
}
void find()
{
Getnext();
int n=strlen(T);
int m=strlen(P);
int j=0;
for(int i=0; i<n; i++)
{
while (j && T[i]!=P[j])
{
j=next[j];
}
if(T[i]==P[j])
{
j++;
}
if(j==m)
{
cnt++;
}
}
}
void Getnext()
{
int i=0;
int j=-1;
int p=strlen(P);
next[0]=-1;
while (i<p)
{
if (j==-1 || P[i]==P[j])
{
i++;
j++;
next[i]=j;
}
else
{
j=next[j];
}
}
}
若上个例题改为不可重复,则代码实现为:
#include<string.h>
using namespace std;
const int N=1e6+5;
char T[N],P[N];
int next[N];
int cnt;void find();
void Getnext();
int main()
{
scanf("%s %s",T,P);
find();
printf("%d\n",cnt);
return 0;
}
void find()
{
Getnext();
int n=strlen(T);
int m=strlen(P);
int j=0;
for(int i=0; i<n; i++)
{
if(j && T[i]!=P[j])
{
j=next[j];
}
if(T[i]==P[j])
{
j++;
}
if(j==m)
{
cnt++;
j=0;
}
}
}void Getnext()
{
int i=0;
int j=-1;
int p=strlen(P);
next[0]=-1;
while (i<p)
{
if (j==-1 || P[i]==P[j])
{
i++;
j++;
next[i]=j;
}
else
{
j=next[j];
}
}
}
相关题目:
这是本人第一次写博客,如有不对请多包涵,如果对您有所帮助请继续支持。