​​


例题:

[KMP] 对最长前后缀匹配表生成步骤的理解_初始化

输入样例:

3
aba
5
ababa

输出样例:

0 2

 代码实现:

#include <iostream>
#include <cstring>
using namespace std;

const int N = 1e5+10, M = 1e6+10;

int n, m;
int ne[N];
char s[N], g[M];

int main()
{
cin >> n >> s + 1 >> m >> g + 1;

//模式串自匹配,初始化偏移数组ne[]
for(int i = 2, j = 0; i <= n; i ++)
{
while(j && s[j+1] != s[i]) j = ne[j];
if(s[j+1] == s[i]) j ++;
ne[i] = j;
}

//两串匹配
for(int i = 1, j = 0; i <= m; i ++)
{
while(j && s[j+1] != g[i]) j = ne[j];
if(s[j+1] == g[i]) j ++;
if(j == n)
{
cout << i-n << " "; //题意中下标从0开始,因此(i-n+1)-1
j = ne[j];
}
}

return 0;
}

下面我们输出关键的ne[ ]数组(即最长前后缀匹配表)初始化的步骤

#include <iostream>
#include <cstring>
using namespace std;

const int N = 1e5+10, M = 1e6+10;

int n, m;
int ne[N];
char s[N], g[M];

int main()
{
cin >> n >> s + 1 >> m >> g + 1;

//模式串自匹配,初始化偏移数组ne[]
for(int i = 2, j = 0; i <= n; i ++)
{
cout << "-----------" << endl;
while(j && s[j+1] != s[i]){
printf("s[j(%d)+1] != s[i(%d)] 👉'%c' != '%c'\n", j, i, s[j+1], s[i]);
j = ne[j];
printf("j = ne[j] (ne[%d]) = %d\n", j, ne[j]);
}
if(s[j+1] == s[i]){
printf("s[j(%d)+1] == s[i(%d)] 👉'%c' != '%c'\n", j, i, s[j+1], s[i]);
j ++;
printf("j++, j = %d\n", j);
}
ne[i] = j;
printf("ne[i(%d)] = j(%d)\n", i, j);
}
cout << "-----------" << endl;
for(int i = 1; i <= n; i ++) cout << ne[i] << " ";
cout << "#" << endl;
//两串匹配
// for(int i = 1, j = 0; i <= m; i ++)
// {
// while(j && s[j+1] != g[i]) j = ne[j];
// if(s[j+1] == g[i]) j ++;
// if(j == n)
// {
// cout << i-n << " ";
// j = ne[j];
// }
// }

return 0;
}

测试输入:

10
ababcabcab
14
abababababccba

(注: 字符串下标从1开始)




s[]



a



b



a



b



c



a



b



c



a



b



ne[]



0



0



1



2



0



1



2



0



1



2



下标



1



2



3



4



5



6



7



8



9



10



对比参照输出: 

(括号内表示的是i / j此时的值)

----------- ne[i(2)] = j(0) ----------- s[j(0)+1] == s[i(3)] 👉'a' == 'a' j++, j = 1 ne[i(3)] = j(1) ----------- s[j(1)+1] == s[i(4)] 👉'b' == 'b' j++, j = 2 ne[i(4)] = j(2) ----------- s[j(2)+1] != s[i(5)] 👉'a' != 'c' j = ne[j(0)] = 0 ne[i(5)] = j(0) ----------- s[j(0)+1] == s[i(6)] 👉'a' == 'a' j++, j = 1 ne[i(6)] = j(1) ----------- s[j(1)+1] == s[i(7)] 👉'b' == 'b' j++, j = 2 ne[i(7)] = j(2) ----------- s[j(2)+1] != s[i(8)] 👉'a' != 'c' j = ne[j(0)] = 0 ne[i(8)] = j(0) ----------- s[j(0)+1] == s[i(9)] 👉'a' == 'a' j++, j = 1 ne[i(9)] = j(1) ----------- s[j(1)+1] == s[i(10)] 👉'b' == 'b' j++, j = 2 ne[i(10)] = j(2) ----------- 0 0 1 2 0 1 2 0 1 2 #