KMP
基础
下文的字符串下标皆从
考虑定义一个数组
是不是觉得很绕?我们举一个例子来更好的说明:
考虑 abababc
。那么
然后我们考虑如何快速求出
有一个显然的结论,
于是我们可以分类讨论,对
-
相等,此时
。 -
否则,我们考虑令
,判断 是否等于 并重复这一过程。
为什么在否则时我们的做法是正确的,可以看一下图:
然后这样做的时间复杂度是线性的,可以看一下题目。
题目
KMP
板子题,可以直接看一下代码:
#include<bits/stdc++.h>
#define int long long
#define N 1000005
using namespace std;
int ne[N],j,len1,len2;
char s1[N],s2[N];
signed main(){
cin>>(s1+1)>>(s2+1);
len1=strlen(s1+1);len2=strlen(s2+1);
for(int i=2;i<=len2;i++){
while(j&&s2[i]!=s2[j+1])j=ne[j];
if(s2[i]==s2[j+1])j++;
ne[i]=j;
}
j=0;
for(int i=1;i<=len1;i++){
while(j&&s1[i]!=s2[j+1])j=ne[j];
if(s1[i]==s2[j+1])j++;
if(j==len2){
cout<<i-len2+1<<'\n';
j=ne[j];
}
}
for(int i=1;i<=len2;i++)cout<<ne[i]<<' ';
return 0;
}
Compress Words
幽默题,坑点很多。
考虑设当前的答案为
于是你超时了。
为什么呢?如果第一个字符串非常长,你还每次都跑一遍,那么复杂度为
所以要优化,设当前
于是你又挂了。
为什么呢?看这样一个数据:101 010
,你求出来的
代码:
#include<bits/stdc++.h>
#define int long long
#define N 1000005
using namespace std;
int n,ne[N];
string s,t,res;
void kmp(string s){
int len=s.size();
s=' '+s;
ne[0]=ne[1]=0;
int j=0;
for(int i=2;i<=len;i++){
while(j&&s[i]!=s[j+1])j=ne[j];
if(s[i]==s[j+1])j++;
ne[i]=j;
}
}
signed main(){
cin>>n;
while(n--){
cin>>s;
int len=min(s.size(),res.size());
t=s+'|'+res.substr(res.size()-len,len);
kmp(t);
for(int i=ne[t.size()];i<s.size();i++){
res+=s[i];
}
}
cout<<res;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】