KMP算法是我不想写的一个算法,原因也很简单,我可以按照算法的思路写出代码实现字符串模式匹配,但是我发现我还是不太能解释这个算法。好像有句话说的是,不能把一个东西解释给别人听,本质上还是没有完全理解。所以我也不确定我这次能不能很好地解释这个算法,毕竟上次其实也写过KMP算法的博客,但最后还是没能好好地把这个算法讲明白了,比较遗憾。
好,既然这次我决定重新讲解这个算法,我一定尽力不留遗憾 :)(丢,去TM的遗憾)
KMP算法的时间复杂度为O(M+N),取得这个时间复杂度的主要原因是它避免了回溯。
KMP算法的核心其实就是next数组,利用next数组可以得出模式串右移的步数。
计算next数组的代码如下:
vector<int> GetNext(vector<char> p)
{
int pLen = p.size();
vector<int> next(pLen);
next[0] = -1;
int k = -1;
int j = 0;
while (j < pLen - 1)
{
//p[k]表示前缀,p[j]表示后缀
if (k == -1 || p[j] == p[k])
{
++k;
++j;
next[j] = k;
}
else
{
k = next[k];
}
}
return next;
}
KMP查找模式串代码:
int KMPSearch(vector<char> s,vector<char> p)
{
vector<int> next = GetNext(p);
int sSize = s.size();
int pSize = p.size();
int i = 0, j = 0;
while (i < sSize && j<pSize)
{
if (j==-1 || s[i]==p[j])
{
i++;
j++;
}
else
{
j = next[j];
}
}
if (j == pSize)
{
return i - j;
}
else
{
return -1;
}
}
嘻嘻嘻,我把代码背下来了 :)