給定一個模式串S,以及一個模板串P,所有字符串中只包含大小寫英文字母以及阿拉伯數字。 模板串P在模式串S中多次作爲子串出現。 求出模板串P在模式串S中所有出現的位置的起始下標。
輸入格式
第一行輸入整數N,表示字符串P的長度。
第二行輸入字符串P。
第三行輸入整數M,表示字符串S的長度。
第四行輸入字符串S。
輸出格式
共一行,輸出所有出現位置的起始下標(下標從0開始計數),整數之間用空格隔開。
數據範圍
1≤N≤104
1≤M≤105
輸入樣例:
3
aba
5
ababa
輸出樣例:
0 2
#include <iostream>
using namespace std;
const int N = 10010, M = 100010;
int n, m;//模式串和子串的長度
char p[N], s[M];//p是模板串, s是模式串
int ne[N];//next數組,取當前字符最大前綴後綴相等的個數,也就是最長公共前綴
int main()
{
cin >> n >> p + 1 >> m >> s + 1;//輸入長度及串內容
//求next的過程
ne[1] = 0;//下標從1開始
for(int i = 2, j = 0; i <= n; i ++ )
{
while(j && p[i] != p[j + 1])
j = ne[j];
if(p[i] == p[j + 1]) j ++ ;
ne[i] = j;
}
//KMP匹配過程
for(int i = 1, j = 0; i <= m; i ++ )
{
while(j && s[i] != p[j + 1])
j = ne[j];
if(s[i] == p[j + 1])
j ++ ;
if(j == n)
{
//匹配成功
printf("%d ", i - n );
j = ne[j];
}
}
return 0;
}
理解 + 記憶