KMP算法真是看了很久很久,看很简单,关键是自己写起来还得好好理解理解
个人觉得KMP算法重点要掌握i,j,next的含义,啥也不说了,看了两天,终于调处来了,直接上代码吧。。。。。
代码:
运行时间:4ms
class Solution {
public:
int strStr(string haystack, string needle) {
if(haystack == "" && needle == "") return 0;
if(haystack == "" && needle != "") return -1;
if(haystack != "" && needle == "") return 0;
int i = 0;
int j = 0;
int HLen = haystack.length();
int NLen = needle.length();
/*next[i]匹配方式:
如果next[i] = -1则目标串pD向右移一位,同时模式串指针pP移到0;
如果next[i] != -1则目标串pD不变,同时模式串指针pP移到next[i];
*/
vector<int> next(NLen, 0);
getNext(needle, next);
while(i < HLen && j < NLen){
if(haystack[i] == needle[j]){
if(j == NLen) return i - NLen + 1;
i++;
j++;
}
else{
if(next[j] == -1){
j = 0;
i++;
}
else{
j = next[j];
}
}
}
if(j == NLen) return i - NLen;
else return -1;
}
private:
//网上看到的KMP算法,比较简洁,但是不是特别好理解
/* void getNext(string pattern, vector<int> &next){
int j = -1; //标记现在的匹配位置
int i = 0; //next下标
int sLen = pattern.length();
next[0] = -1;
if (sLen == 1) return;
while(i < sLen - 1){
if(j == -1 || pattern[i] == pattern[j]){
i++;
j++;
next[i] = pattern[i] != pattern[j] ? j : next[j];
}
else{
j = next[j];
}
}
}*/
//自己经过理解之后写的KMP算法,代码不是很简洁,但是比容易理解
void getNext(string pattern, vector<int> &next){
int j = 0; //标记现在的匹配位置
int i = 1; //next下标
int sLen = pattern.length();
/*next[i]匹配方式:
如果next[i] = -1则目标串pD向右移一位,同时模式串指针pP移到0;
如果next[i] != -1则目标串pD不变,同时模式串指针pP移到next[i];
*/
next[0] = -1; //如果当前不匹配,那么下一个要找的匹配键值next[k];
if (sLen == 1) return;
while (i < sLen){
if (j == -1){
j++;
next[i] = pattern[i] == pattern[j] ? next[j] : j;
i++;
}
else{
if (pattern[i] != pattern[j]){
next[i] = j;
i++;
j = next[j]; //说明到此为止,能够重复的字符应该往回走了
}
else{
next[i] = next[j];
i++;
j++;
}
}
}
}
};