一、引言
- KMP又称模式匹配算法,能够在线性时间内判定字符串A[1~N]是是否为B[1 ~ M]的子串,并求出A在B中各次出现的位置。
二、基本含义
- next数组:next[i] 代表A中以i结尾的非前缀子串(非前缀子串的意思就是不能和A完全相等的后缀子串) 与 A的前缀能够匹配的最大长度。
- 当不存在这样的前缀串时,显然next[i] = 0, 故next[1] = 0 (因为第一个字符前面没有字符串且第一个字符不是非前缀子串)
- 我们可以让A对B进行匹配,求出一个数组p。p[i]代表以i结尾的子串 与 A的前缀能够匹配的最大长度。 当p[i] = n(A的长度)代表匹配此位置成功。
三、next数组的求解
1. 朴素的求解next数组
- 假定A串为 abababbc
2. 优化求解next数组过程
void getNext() {
for (int i = 2, j = 0; i <= n; i++) {
while (j && A[i] != A[j + 1]) j = ne[j];
if (A[i] == A[j + 1]) j++;
ne[i] = j;
}
}
三、kmp算法
- 这时候我们与串B匹配的过程和求解next的过程大同小异。
void kmp() {
for (int i = 1, j = 0; i <= m; i++) {
while (j && B[i] != A[j + 1]) j = ne[j];
if (B[i] == A[j + 1]) j++;
p[i] = j;
}
}
四、其他应用
- 最小循环节