洛谷P3375 【模板】KMP字符串匹配(KMP)
题目描述
如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置。
为了减少骗分的情况,接下来还要输出子串的前缀数组next。
(如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习一下就知道了。)
输入格式
第一行为一个字符串,即为s1
第二行为一个字符串,即为s2
输出格式
若干行,每行包含一个整数,表示s2在s1中出现的位置
接下来1行,包括length(s2)个整数,表示前缀数组next[i]的值。
输入输出样例
输入
ABABABC ABA
输出
1 3 0 0 1
说明/提示
时空限制:1000ms,128M
数据规模:
设s1长度为N,s2长度为M
对于30%的数据:N<=15,M<=5
对于70%的数据:N<=10000,M<=100
对于100%的数据:N<=1000000,M<=1000000
样例说明:
所以两个匹配位置为1和3,输出1、3
1 #include <cstdio> 2 #include <cstring> 3 using namespace std; 4 5 const int N=1e6+5; 6 int next[N]; 7 8 void getnext(char *s2){ 9 int len=strlen(s2); 10 next[0]=-1; 11 for(int i=0,j=-1;i<len;){ 12 if(j==-1||s2[i]==s2[j]) 13 next[++i]=++j; 14 else j=next[j]; 15 } 16 } 17 18 void KMP(char *s1,char *s2){ 19 getnext(s2); 20 int l1=strlen(s1),l2=strlen(s2); 21 int i=0,j=0; 22 while(j<l1){ 23 if(s2[i]==s1[j]){ 24 i++,j++; 25 if(i==l2){ 26 printf("%d\n",j-l2+1); 27 i=next[i-1]+1; 28 } 29 } 30 else{ 31 if(i==0) j++; 32 else i=next[i-1]+1; 33 } 34 } 35 } 36 37 int main(){ 38 char s1[N],s2[N]; 39 scanf("%s%s",s1,s2); 40 KMP(s1,s2); 41 int len=strlen(s2); 42 for(int i=1;i<=len;i++){ 43 if(i!=1) printf(" "); 44 printf("%d",next[i]); 45 } 46 printf("\n"); 47 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步