KMP
KMP O(n)
ZERO版
next[i]:在i之前的子串和从0开始的最大相等子串长度-1
ne[i]=j:i的位置失配该回退的位置j
// 下标从0开始
// s是长文本, t是模式串
// 求模式串的next数组:
int ne[t.size()];
ne[0] = -1;
for (int i = 1, j = -1; i < t.size(); i ++ )
{
while (j >= 0 && t[i] != t[j + 1]) j = ne[j];
if (t[i] == t[j + 1]) j ++ ;
ne[i] = j;
}
// 匹配
for (int i = 0, j = -1; i < s.size(); i ++ )
{
while (j >= 0 && s[i] != t[j + 1]) j = ne[j];
if (s[i] == t[j + 1]) j ++ ;
if (j == t.size() - 1)
{
int pos = i - j;
/* ...匹配成功后的逻辑... */
j = ne[j]; // 继续回溯查找
}
}
ONE版
next[i]:表示以i为终点的后缀和从1开始的前缀相等,而且前后缀的长度最长
next[i]=j:表示在i的位置上, p[1~j] == p[i-j+1,i] 这两段子串相等
// 下标从1开始
// s[]是长文本, p[]是模式串, n是s的长度, m是p的长度
// 求模式串的next数组:
for (int i = 2, j = 0; i <= m; i ++ )
{
while (j && p[i] != p[j + 1]) j = ne[j];
if (p[i] == p[j + 1]) j ++ ;
ne[i] = j;
}
// 匹配
for (int i = 1, j = 0; i <= n; i ++ )
{
while (j && s[i] != p[j + 1]) j = ne[j];
if (s[i] == p[j + 1]) j ++ ;
if (j == m)
{
int pos = i - j;
/* ...匹配成功后的逻辑... */
j = ne[j];
}
}

浙公网安备 33010602011771号