KMP算法理解
- next数组
设模式串p,长度n,则next数组长度为n。
设0<=i<=j<n,p中存在长度L的子串使得i和j之间有且只有 p[j-L,…,j-1]==p[i-L,…,i-1] ,且该子串是p的前缀,则next[j]=i。
next[j]=i的作用在于,假设s为被匹配串,当匹配到p[j]和s[k]时,p[j]!=s[k],则进行p[next[j]]与s[k]匹配,避免了重头匹配p。
void getNext(string p, vector<int>& next)
{
int n = p.size();
next.resize(n);
next[0] = -1;
int j = 0;
int k = -1;
while(j < n-1)
{
if(k == -1 || p[j] == p[k])
{
next[++j] = ++k;
}
else
{
k = next[k];
}
}
}
- 匹配
匹配成功的条件就是p被遍历完了。
int kmp(string p, string s)
{
int m = p.size();
int n = s.size();
if(m > n) return false;
vector<int> next;
getNext(p, next);
int j = 0;
int k = 0;
while(j < m && k < n)
{
if(j == -1 || p[j] == s[k])
{
++j;
++k;
}
else
{
j = next[j];
}
}
if(j >= m) return k-m;
return -1;
}