kmp算法思想 博客:https://kb.cnblogs.com/page/176818/
kmp算法 视频:https://www.bilibili.com/video/av16828557?from=search&seid=11169755781803162143
kmp 字符串匹配的话
需要 next 数组
短字符串有可能会含有相同的字符字串
所以需要一个next数组存放 前一个字符为尾的连续字符(不含自身字符) 与从第一个字符开始相同的最后一个字符子串的位置(也就是存放 该字符(不含该字符)前边的字符串中 相同的前缀和后缀–后缀的位置)
也就是:
abcdeabc
相当于运行到b时 next数组的当前位置 存放的是b前边的a与第一个字符相同的位置 也就是 abcdeabc 里面a的位置:0
abcdeabc
相当于运行到c时 next数组的当前位置 存放的是c前边的b与第一个字符相同的位置 也就是 abcdeabc 里面ab中 b 的位置:1
感觉我bb的不是很清楚,不清楚就看看代码,看几遍就可了。
数据结构实验之串一:KMP简单应用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int next[1000005];
char s1[1000005];
char s2[1000005];
void build()
{
int l=strlen(s2);
int i=0,j=-1;
next[0]=-1;
while(i<l)
{
if(s2[j]==s2[i]||j==-1)
{
i++;
j++;
next[i]=j;
}
else j=next[j];
}
}
int kmp()
{
int i=0, j=0;//s2;
int le1=strlen(s1), le2=strlen(s2);
while(i<le1&&j<le2)
{
if(s1[i]==s2[j]||j==-1) i++,j++;
else j=next[j];
}
if(j==le2) return i-j+1;
else return -1;
}
int main()
{
while(~scanf("%s",s1))
{
scanf("%s",s2);
build();
int x=kmp();
printf("%d\n",x);
}
return 0;
}
数据结构实验之串二:字符串匹配
原题链接:https://acm.sdut.edu.cn/onlinejudge3/problems/2125
跟上一个题差不多
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s1[105],s2[105];
int next[105];
void build()
{
int i=0,j=-1,l;
l=strlen(s2);
next[0]=-1;
while(i<l)
{
if(s2[i]==s2[j]||j==-1)
{
i++;
j++;
next[i]=j;
}
else j=next[j];
}
}
void kmp()
{
int i=0,le1;//s1
int j=0,le2;//s2
le1=strlen(s1);
le2=strlen(s2);
while(i<le1&&j<le2)
{
if(s1[i]==s2[j]||j==-1)
{
i++;
j++;
}
else j=next[j];
}
if(j==le2) printf("YES\n");
else printf("NO\n");
}
int main()
{
while(~scanf("%s%s",s1,s2))
{
build();
kmp();
}
return 0;
}
数据结构实验之串三:KMP应用
原题链接:https://acm.sdut.edu.cn/onlinejudge3/problems/3311
题目有个坑:唯一
再就是把字符串换成数组就能A了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int next[100005];
int a[1000005],b[100005];
int n,m;
void build()
{
int i=0,j=-1;
next[0]=-1;
while(i<m)
{
if(b[i]==b[j]||j==-1)
{
i++;
j++;
next[i]=j;
}
else j=next[j];
}
}
int kmp(int i,int j)
{
while(i<n&&j<m)
{
if(a[i]==b[j]||j==-1)
{
i++;
j++;
}
else j=next[j];
}
if(j==m) return i-j+1;
else return -1;
}
int main()
{
int i;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
scanf("%d",&m);
for(i=0;i<m;i++)
scanf("%d",&b[i]);
build();
int k=kmp(0,0);
if(k!=-1)
{
int t=kmp(k+m-1,next[m]);
if(t==-1) printf("%d %d\n",k,k+m-1);
else printf("-1\n");
}
else printf("-1\n");
return 0;
}