28.实现strStr()
今天看了串,主要是学习KMP算法,所以在力扣上找了一个模式匹配的题,虽然这个题用暴力,用一句调用(!!!)就可以过,但是主要是为了练一下KMP啦
- 题目描述
实现 strStr() 函数。
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
28.实现strStr()
- 分析KMP
KMP真的很难记,理解起来也很麻烦
浅浅描述一下:
模式匹配就是在主串中寻找子串(也就是模式)出现的位置。
我们用i指针指向主串,用j指针指向模式。
暴力匹配 就是,首先让i,j都指向字符串中第一个位置(从1开始编号),即i = 1 , j = 1;
若该字符匹配成功,则i++、j++继续匹配,直至完全匹配。
若匹配失败,则i回退到i - j + 1,j回退到1,重新开始匹配。
//
KMP算法 中,i不需要回退
而是当匹配失败时,使j指向 next[ j ] 的位置,再使i,j进行匹配。
//
next[j] 是啥捏?
next[j] = k , k 是使得模式中’1…k-1’位置的子串与’j-k+1…j-1’位置的子串相等的位置
k满足 1<k<j , 且不存在 k’ > k满足上式
//
next[j] 怎样计算捏?
下面是一个类似于数学归纳法的推理(手动狗头)
//*******************************************************//
1.由定义我们知 next[1] = 0
2.设 next[j] = k , 则有 模式中’1…k-1’位置的子串与’j-k+1…j-1’位置的子串相等
3.求next[j+1]
(1)若k位置的字符与j位置的字符相等,则有 模式中’1…k’位置的子串与’j-k+1…j’位置的子串相等
即有 next[j+1] = k+1 => next[j+1] = next[j] + 1
(2)若k位置的字符与j位置的字符不相等,则此时可以把问题转化为模式匹配的问题(我也很无语,我也很绕,我的脑袋也不够用)
整个模式串即是主串,又是模式串
k = next[k]
在实现中,为避免j位置的字符与next[j]的字符相同而是我们的移动没有意义,还要加上一个判断条件
//
友友们我找到了一个讲的很好的博主,可以看一下,超级清晰
顶呱呱的博主
- 代码
呜呜终于到代码部分了
class Solution {
public:
int strStr(string haystack, string needle) {
int i = 0 ;
int j = 0 ;
int *next = get_next(needle);
if(needle.empty())
return 0;
int hl = haystack.length();
int nl = needle.length();
while(i < hl && j < nl){
if(j == -1 || haystack[i] == needle[j]){
i++;j++;
}
else{
j = next[j];
}
}
if(j == needle.length()){
return i - j;
}
else
return -1;
}
int *get_next(string needle){
int j = 0;
int k = -1;
int next[10005] = {0};
next[0] = -1;
while(j < needle.length() - 1){
if(k == -1 || needle[j] == needle[k]){
j++;k++;
if(needle[j] == needle[k]){
//即j位置的字符与next[j]的字符相同
next[j] = next[k];//跳过
}
else{
next[j] = k;
}
}
else{
k = next[k];
}
}
return next;
}
};
真的是太难了呜呜呜