You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

59 lines
3.4 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
const int N = 100010; //模板串最大长度限制
const int M = 1000010; //模式串最大长度限制
int n; //模板串长度
int m; //模式串长度
int ne[N]; //next数组
char s[M]; //模式串
char p[N]; //模板串
/**
KMP
1
2
3退退
4
退退,
KMPne
ne[j]
j()
-()
*/
int main() {
cin >> n >> (p + 1) >> m >> (s + 1);
//一、求ne数组
//i:当前试图进行匹配的S串字符j+1是模板串当前试图与S串i位置进行匹配的字符
//j:退无可退,无需再退
//i:是从2开始的因为ne[1]=0,表示第1个不匹配只能重头开始不用算
for (int i = 2, j = 0; i <= n; i++) {
while (j && p[i] != p[j + 1]) j = ne[j];
//如果是匹配情况发生了那么j移动到下一个位置
if (p[i] == p[j + 1]) j++;
//记录j到ne数组中
ne[i] = j;
}
/**
KMPijne[j]
j = ne[j] = 0退i
ji++j++
*/
//二、匹配字符串
//i:当前试图进行对比的S串位置
//j:最后一个已完成匹配的P串位置那么当前试图与S串当前位置i进行尝试对比匹配的位置是j+1
for (int i = 1, j = 0; i <= m; i++) {
while (j && s[i] != p[j + 1]) j = ne[j];//不行就退吧,当j==0时表示退无可退无需再退
//如果是匹配情况发生了那么j移动到下一个位置
if (s[i] == p[j + 1]) j++; //匹配则指针前行i不用++因为它在自己的for循环中自带++
if (j == n) { //如果匹配到最大长度,说明完成了所有位置匹配
printf("%d ", i - n); //输出开始匹配位置
j = ne[j]; //回退,尝试继续进行匹配,看看还有没有其它可以匹配的位置
}
}
return 0;
}