思路
kmp 求单个字符串在主串 s 中的出现的位置、次数,还要考虑能不能算法重叠算不算贡献。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;
int n, m;
char s[N], t[N];
int nxt[N], mk[N];
void get_nxt()
{
int j = 0, k = -1;
nxt[0] = -1;
while (j < m)
{
if (k == -1 || t[j] == t[k])
{
j ++, k ++;
if (t[j] == t[k])
nxt[j] = nxt[k];
else
nxt[j] = k;
}
else
k = nxt[k];
}
}
void kmp() //kmp 多次重叠匹配
{
int i = 0, j = 0;
while (i < n && j < m)
{
if (j == -1 || s[i] == t[j])
i ++, j ++;
else
j = nxt[j];
if (j == m)
{
mk[i - 1] = 1; //标记每个匹配串的结尾
j = nxt[j]; //根据多重匹配的性质来跳的!!!
}
}
}
void init()
{
memset(mk, 0, sizeof mk);
memset(nxt, 0, sizeof nxt);
}
int main()
{
init();
scanf("%d %s %d %s", &m, t, &n, s);
get_nxt();
kmp();
for (int i = 0; i < n; i ++)
{
if (mk[i]) printf("%d ", i - m + 1);
}
return 0;
}