初涉KMP算法
2016-11-08 22:56 Hold_F 阅读(172) 评论(0) 收藏 举报做了几道题之后,总结几个自己认为的重点吧。
算法是为了解决在文本串中寻找模式串的问题。常规暴力方法,是在文本串(m)中遍历每个位置作为开始和模式串(n)进行匹配,时间复杂度O(mn)。而KMP的做法,是先对模式串进行一个预处理,使复杂度降到O(m+n)。
算法的核心就是对模式串进行预处理,构造一个名为next的前缀数组。
定义nxt[i]为模式串中第i个字符失匹配后指向的位置,或者说位置i之前的字符串的前缀和后缀公共部分的最大长度。
好理解一点的写法:
void getNext(char *p){
int j = 0,k = -1;
int len = strlen(p);
next[0] = -1;
while(j < len){
if(k == -1 || p[j] == p[k]){ //如处于初始位置,或者匹配成功
j++;
k++;
next[j] = k;
}
else k = next[k];
}
}
另一种简练点的写法:
void getNext(char * p){
nxt[0] = -1;
int len = strlen(p);
for(int i = 0; i < len; i++){
int k = nxt[i];
while(k != -1 && p[i] != p[k]) k = nxt[k]; //如匹配不成功,就去找上一个位置尝试匹配
nxt[i+1] = k + 1;
}
}
KMP匹配函数
bool kmp(char *s, char *p){
getNext(p);
int lens = strlen(s), lenp = strlen(p);
int i = 0, j = 0;
while(i < lens && j < lenp){
while(j != -1 && s[i] != p[j]) j = nxt[j];
++i;
++j;
}
if(j == lenp) return true;
return false;
}
总结KMP应用:
1、文本串中寻找模式串
2、串的前缀和后缀匹配问题
3、串的循环节问题
一句话来总结KMP,就是当匹配不成功时,模式串返回到失配字符前的最大相同前缀接着匹配的算法。
浙公网安备 33010602011771号