文章目录
KMP
KMP算法可以在线性的时间中完成字符串匹配问题。
时间复杂度:
O
(
n
+
m
)
O(n+m)
O(n+m)
在KMP算法中,对于
s
中每一个位置i
,我们要找到最大的j
满足s[i-j+1] … s[i]
和p[1] … p[j]
是相同的。假设我们已经知道了一个位置
i
所对应的j
的值如果
j
不在字符串的末尾,并且s[i+1]
和p[j+1]
是一样的,j也向右移一位;
否则,我们需要让j
回到满足串s[i-k+1] … s[i]
和p[1] … p[k]
完全相等且k的值最大的位置,再继续判断;
如何求k
其实我们要求的是最大的k满足k<j,使得p[1] … p[k]
和p[j-k+1] … p[j]
相等,我们用next数组维护每一个j对应的k。
所以,我们通过对p来进行操作来求出next数组。
// s[]是长文本,p[]是模式串,n是s的长度,m是p的长度
int n, m;
int ne[M + 1], f[N + 1];
char s[N + 2], p[M + 2];
void kmp()
{
n = strlen(s + 1);
m = strlen(p + 1);
ne[1] = 0;
//求模式串的Next数组:
for (int i = 2, j = 0; i <= m; i++)
{
while (j > 0 && 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 == m) || (j > 0 && s[i] != p[j + 1]))
j = ne[j];
if (s[i] == p[j + 1])
j++;
f[i] = j;
}
}