KMP算法简单实现(今天LNG 0:3 T1,该配合你演出的我演视而不见)
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 计算模板串S在文本串T中出现了多少次
* @param S string字符串 模板串
* @param T string字符串 文本串
* @return int整型
*/
int kmp(string S, string T) {
// write code here
int s = S.size(),t = T.size();
//模式串比主串长的话
if (S.empty() || s > t) {
return 0;
}
int res = 0,next[s-1];
//next[x]的意义是长度为x的前子串最长相同前后缀长度
next[0] = -1;
//第0位设置成-1 表示需要右移被匹配字符指针
//先用双指针在模板内进行匹配
for (int pre = -1, now = 0; now < s; ) {
if(pre == -1 || S[pre] == S[now]){
pre++;
now++;
//左右指针
next[now] = pre;
}else {
pre = next[pre];
}
}
//现在模式串和文本串进行匹配
for (int patt = 0,now = 0; now < t; ) {
if (patt == -1 || S[patt] == T[now]) {
patt++;
now++;
//大小指针
if (patt == s) {//完全匹配的情况
res++;
patt = next[patt];
}
}else {
patt = next[patt];
}
}
return res;
}
};
KMP算法和朴素匹配(也称为暴力匹配)的区别
1. 匹配方式不同:
朴素匹配:从文本串的第一个字符开始,依次与模式串的每个字符进行比较,如果不匹配则移动文本串的指针,继续从下一个字符开始比较。
KMP算法:通过预处理模式串的next数组,根据已经匹配的前缀信息,确定模式串的下一个比较位置,从而避免重复匹配已经匹配过的字符。
2. 时间复杂度不同:
朴素匹配的时间复杂度为O(m*n),其中m为模式串的长度,n为文本串的长度。
KMP算法的时间复杂度为O(m+n),其中m为模式串的长度,n为文本串的长度。由于KMP算法避免了重复匹配,所以在大部分情况下,KMP算法的效率要高于朴素匹配。
3. 空间复杂度不同:
朴素匹配的空间复杂度为O(1),不需要额外的空间。
KMP算法的空间复杂度为O(m),需要额外的空间来存储模式串的next数组。
总结:KMP算法通过预处理模式串的next数组,可以在匹配过程中避免重复匹配已经匹配过的字符,从而提高匹配效率。相比之下,朴素匹配没有使用额外的空间,但效率较低。

京公网安备 11010502036488号