课上学了KMP算法之后有几个地方很是迷茫,课下就查了点资料,这里做下总结,今后忘了还能回来看一下。
首先,KMP算法的主要目的就是比较两个字符串时避免不必要的回溯。一个字符串可能会出现字符串头部和尾部有重复的现象,KMP算法就是根据这个现象,在比较字串时,不在简单地向后移一位,而是在后移时,跳过首位相同的部分再开始比较。例如:判断 ABCDABD 是否是 ABCDABEABCDABD 的子串,
ABCDABEABCDABD
ABCDABD
判断到第6位时 E 和 D 不同,但它的前两位 AB 和 子串的前两位 AB 相同,所以之后直接移动到
ABCDABEABCDABD
ABCDABD
所以这时子串和 E 比较的位的 C 的下标就等于 D 的前一位 B 的首位重复的位数
这里就需要对子串进行一个预处理,就是算出它的每一位对应的部分匹配值,也就是前后重复的位数,对于 ABCDABD 来说,就是 0000120,先上代码
#include <string>
#include <assert.h>
int* Next(string P){
int m = P.length();
assert( m > 0 ); //若 m = 0 则退出
int *N = new int[m];
assert( N != NULL );
N[0] = 0;
for(int i = 1; i < m; i ++){
int k = N[i - 1];