首先需要知道前缀和后缀的概念
前缀:指的是字符串的子串中从原串最前面开始的子串,不会加入最后的字符,如abab的前缀有:a,ab,aba
后缀:指的是字符串的子串中在原串结尾处结尾的子串,不会加入第一个字符,如abab的后缀有:b,ab,bab
接着是next数组:
next[i]
的值就是i下标之前的字符串的最长公共前缀和后缀的长度。如abab的
next[4]
,看上面前缀后缀的部分可以知道,公共的前缀后缀为ab,则
next[4]=2
。
最后就是通过next数组进行KMP匹配算法。
next数组代码:
void GetNext(string B)
{
int len_B = B.size();
nex[0] = -1;
int k = -1,j = 0 ;
while(j < len_B)
{
if(k == -1 || B[j] == B[k])
{
++ k; ++ j;
nex[j] = k;
}
else
k = nex[k];
}
}
KMP函数模板:
int kmp(string A, string B)
{
int ans = -1, i = 0, j = 0;
int len_B = B.size(), n = A.size();
while(i<n)
{
if(j==-1||A[i] == B[j])
{
++i;
++j;
}
else
j = nex[j];
if(j == len_B)
{
return i-len_B + 1; //A数组从0开始所以应返回的位置+1.
}
}
return ans;
}
POJ-1961
POJ-3461
POJ-2752
POJ-2406
HDU-2087
HDU-1686
HDU-2203
HDU-1358
HDU-1711
HDU-1238
参考博客:http://blog.youkuaiyun.com/qq_36345036/article/details/77386646