Luogu P3375 【模板】KMP字串匹配
阿新 • • 發佈:2018-11-10
題目描述
如題,給出兩個字串s1和s2,其中s2為s1的子串,求出s2在s1中所有出現的位置。
為了減少騙分的情況,接下來還要輸出子串的字首陣列next。
(如果你不知道這是什麼意思也不要問,去百度搜[kmp演算法]學習一下就知道了。)
輸入輸出格式
輸入格式:
第一行為一個字串,即為s1
第二行為一個字串,即為s2
輸出格式:
若干行,每行包含一個整數,表示s2在s1中出現的位置
接下來1行,包括length(s2)個整數,表示字首陣列next[i]的值。
輸入輸出樣例
輸入樣例#1:
ABABABC
ABA
輸出樣例#1:
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
int j=0; for(int i=1;i<=n;i++) { while(j>0&&s1[i]!=s2[j+1]) j=nxt[j]; if(s1[i]==s2[j+1]) j++; if(j==m) write(i-m+1),puts(""),j=nxt[j]; }
int j=0;
for(int i=2;i<=m;i++)
{
while(j>0&&s2[i]!=s2[j+1]) j=nxt[j];
if(s2[i]==s2[j+1]) j++;
nxt[i]=j;
}
#include<cstdio> #include<cstring> using namespace std; int n,m; const int N=1e6+5; char s1[N],s2[N]; int nxt[N]; void write(int x) { if(!(x/10)) { putchar(x+48); return ; } write(x/10); putchar(x%10+48); } int main() { scanf("%s%s",s1+1,s2+1); n=strlen(s1+1),m=strlen(s2+1); int j=0; for(int i=2;i<=m;i++) { while(j>0&&s2[i]!=s2[j+1]) j=nxt[j]; if(s2[i]==s2[j+1]) j++; nxt[i]=j; } j=0; for(int i=1;i<=n;i++) { while(j>0&&s1[i]!=s2[j+1]) j=nxt[j]; if(s1[i]==s2[j+1]) j++; if(j==m) write(i-m+1),puts(""),j=nxt[j]; } for(int i=1;i<m;i++) write(nxt[i]),putchar(' '); write(nxt[m]); return 0; }