KMP 字符串匹配 学习笔记
前言
最近才发现自己写了后缀数组,但并没有其他的字符串算法,今天先把
算法核心
对于字符串匹配,最朴素的方法就是一个字符一个字符地匹配,找到不同的就直接换一个地方匹配。
我们先来看一组样例:
对于这组样例,暴力的方法就是直接匹配,从第一位开始匹配,发现从第五个地方开始不一样了,那么我们就直接往后移:
发现从第五位开始不一样了,继续往后面移:
以此类推,我们在第五位发现成功匹配了。
不过这样匹配速度太慢了,复杂度为
然后就可以想到预处理出一个数组
然后使得
然后就很清晰了。
数组
自己匹配自己,然后就可以在匹配失败的时候移动到相同的地方以优化。
代码:
for(int i=1;i<m;++i){
while(j>0&&t[j+1]!=t[i+1])
j=p[j];
if(t[i+1]==t[j+1])
++j;
p[i+1]=j;
}
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;
char ch;
ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f=-f;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=x*10+(ch-'0');
ch=getchar();
}
return x*f;
}
char s[10000000],t[10000000];
int n,m,p[11000000];
signed main(){
scanf("%s%s",s+1,t+1);
p[1]=0;
n=strlen(s+1),m=strlen(t+1);
int j=0;
for(int i=1;i<m;++i){
while(j>0&&t[j+1]!=t[i+1])
j=p[j];
if(t[i+1]==t[j+1])
++j;
p[i+1]=j;
}
j=0;
for(int i=0;i<n;++i){
while
j=p[j];
if(t[j+1]==s[i+1])
++j;
if(j==m){
cout<<i-m+2<<endl;
j=p[j];
}
}
for(int i=1;i<=m;++i)printf("%d ",p[i]);
return 0;
}
时间复杂度为:
6666
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧