KMP算法的经典思想就是:当字符串不匹配时,可以记录一些之前已经匹配的内容,不必再从头开始匹配。
实现KMP算法,首先需要构造next数组,构造next数组一共分为三步:
- 初始化
- 前后缀不相同时
- 前后缀相同时
具体构造代码如下:
//构造next数组
void getnext(int *next, const string&s) {
//初始化
int j = 0;
next[0] = 0;
while(int i = 1; i<s.size(); i++) {
//前后缀不相同
while(j>=1 && s[i] != s[j]) {
j = next[j-1];
}
//前后缀相同
if (s[i] == s[j]) {
j = j+1;
}
next[i] = j;
}
}
构造好next数组后,要用next数组来做匹配,在文本串中找是否出现过模式串。
实现代码如下:
//使用next数组进行匹配
int strStr(string haystack, string needle) {
if(needle.size() == 0) return 0;
int next[needle.size()];
getnext(next, needle);
int j = 0;
for(int i = 0; i<haystack.size(); i++) {
//不匹配
while(j>=1 && haystack[i] != needle[j]) {
j = next[j-1];
}
//匹配
if (haystack[i] == needle[j]) {
j = j+1;
}
if(j == needle.size()) {
return (i - needle.size() +1);
}
}
return -1;
}