KMP
实现
现在有两个串a,b:
AAABAAABAAAC
AAAC
要从a中找到b,最简单的方法显然是暴力,那么时间复杂度会非常高,高达
有没有更快的方法?KMP大显身手!
KMP的思想基于最长公共前后缀。
设字符串T=“aabaaf”,我们求一下T的前缀表(用一个数组名为nxt的数组表示)。
- 第一个子串是t0=“a”,易知该子串没有前缀也没有后缀,故nxt[0]=0
- 第二个子串是t1=“aa”,该子串的前缀为"a",后缀也为"a",故nxt[1]=1
- 第三个子串是t2=“aab”,该子串的后缀中一定会有"b",前缀中一定不含有"b",则其没有相等的前后缀,故nxt[2]=0
- 第四个子串是t3=“aaba”,该子串的最大相等前后缀为"a",长度为1,故nxt[3]=1
- 第五个子串是t4=“aabaa”,该子串的最大相等前后缀为"aa",长度为2,故nxt[4]=2
- 第六个子串是t5=“aabaaf”,该子串的后缀中一定会有"f",前缀中一定不含有"f",则其没有相等的前后缀,故nxt[5]=0
所以,这个nxt实际上就是KMP在失配时跳到的位置
板子
get_nxt:
void get_nxt(string x){
int j=0,k=-1,len=x.size();
nxt[0]=-1;
while(j<len){
if(k==-1||x[j]==x[k]){
j++,k++;
nxt[j]=k;
bro[j-1]=k;
}
else{
k=nxt[k];
}
}
}
kmp
void KMP(string s,string t){
int j=0,i=0,slen=s.size(),tlen=t.size();
get_nxt(t);
while(i<slen){
if(j==-1||s[i]==t[j]){
j++,i++;
}
else{
j=nxt[j];
}
if(j==tlen){
cout<<i-tlen+1<<endl;
j=nxt[j];
}
}
}
时间复杂度
本人(KK_SpongeBob)蒟蒻,写不出好文章,但转载请注明原文链接:https://www.cnblogs.com/OIer-QAQ/p/18575261
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期