KMP算法的理解分为两个部分:
1.如何利用next数组(最大前后缀长度)匹配字符。
借助next数组,原字符串的i可以不回移,如果当前字符失配则前模式串的j即可。因为虽然当前s[i]和t[j]失配,但是我们知道j之前的字符是匹配的,只要确定t[0]~t[j-1]的最长前后缀,就可以通过移动j再次匹配s[i]。
http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html这篇文章讲的比较清楚。
2.如何求next数组。
next数组类似于自己和自己作比较,确定当前字符串的最大前后缀长度。
http://www.cnblogs.com/c-cloud/p/3224788.html这篇文章讲的比较清楚。
感觉还是没理解透,过段时间回来继续看。
自己写的代码,要注意各种情况的判断,比如null和“”是不一样的。
class Solution {
public:
int strStr2(const char* source, const char* target) {
if (source==NULL || target==NULL) return -1;
int m = strlen(source);
int n = strlen(target);
if (n==0) return 0;
if (m < n) return -1;
vector<int> next(n,0);
int k = 0;
int i = 1;
for (i; i < n; i++)
{
while (k>0 && (target[k] != target[i]))
k = next[k-1];
if (target[k] == target[i]) k++;
next[k] = k;
}
i = 0;
int j = 0;
while (i<m)
{
while (j>0 && (source[i] != target[j]))
j = next[j - 1];
if (source[i] == target[j]) j++;
if (j == n)
return (i - n + 1);
i++;
}
return -1;
}
};