kmp
我们令第一个字符串为 s,第二个字符串为 t,需要求出 t 在 s 中不重叠的匹配个数。
KMP算法的思想:在匹配 s 的过程中,每次遇到失配的点 s[i]!=t[j],我们应该快速地选择 t[0...j-1] 的 border,实现不往回移动 i 的前提下,快速地完成 s[0...i-1] 的后缀与 t 串前缀的最长匹配,由于外层下标 i 从左至右只走一遍,每次匹配时,j 同 i 一起向前移动,撤回border的次数一定小于向前移动的次数,因此整体时间复杂度为 O(n)
kmp的border 因此,问题转换为如何求出串 t 所有前缀的最大非平凡border,即实现一个前缀函数。
定义 nx[i] 表示 t[0...i] 的最长非平凡border的长度,特别地,nx[0] 为 0。
从 t[1] 开始逐个求前缀函数 t[i] 的过程如下:
1.设border长度的初值 int j = 0;
2.while (j && t[i]!=t[j]) j = nx[j-1];// t[i] 失配时,从长到短依次尝试 t[i-1] 的每一个border
3.if (t[i] == t[j]) ++j;// 若找到了某个border,可以匹配 t[i],匹配长度加 1。
- nx[i] = j;// 记录 t[i] border的长度 给出求nxt的代码
点击查看代码
void match()
{
for (int i = 1, j = 0; t[i]; ++i)
{
while (j && t[i]!=t[j])
j = nx[j-1];
if (t[i] == t[j])
++j;
nx[i] = j;
}
}

浙公网安备 33010602011771号