标签:amp int ++ class res 意义 else 集合 ret
https://www.zhihu.com/question/21923021 的总结
string : 主体字符串 (用 i 遍历)
sptr : 匹配字符串 (用 j 遍历)
string[i] != sptr[j] 时,如果 sptr 前 j-1 部分存在前缀与后缀相同的部分,只需要把 j 移动到前缀+1处,继续 i 和 j 的遍历(此时2个字符串的前面是相同的)
具体实现:string 的同时与 sptr 进行匹配, 如果匹配失败,j = next[j]
代码: (具体题目中不一定是字符串)
int KMP(char *s, char *p) //返回存在与 p 相同的字串的位置
{
int i = 0;
int j = 0;
while(i < strlen(s) && j < strlen(p))
{
if(j == -1 || s[i] == p[j])
{
i++;
j++;
}
else j = next[j];
}
if(j == strlen(p)) return i-j;
else return -1;
}
/*计算相同字串数量
int KMP(char *s, char *p) //返回存在与 p 相同的字串的位置
{
int i = 0;
int j = 0;
int res = 0;
int len_s = strlen(s), len_p = strlen(p); //防TLE
while(i < len_s)
{
if(j == -1 || s[i] == p[j])
{
if(j == len_p-1)
{
res++;
j = next[j];
}
else
{
i++;
j++;
}
}
else j = next[j];
}
return res;
}
*/
pmt[j] 的值表示字符串 ptr 的前缀集合和后缀集合的交集中最长元素的长度(不出现在代码中)
next[j] 是pmt 数组的右移,next[0] = -1, 这么做是为了方便编程,无任何意义
计算 next数组 可以看成 sptr 字符串对自身的匹配,做法与KMP类似
void getNext(char *p, int *next)
{
next[0] = -1;
int i = 0, j = -1;
while(i < strlen(p))
{
if(j == -1 || p[i] == p[j])
{
i++;
j++;
next[i] = j;
}
else j = next[j];
}
}
HDU 1711
POJ 3461
标签:amp int ++ class res 意义 else 集合 ret
原文地址:https://www.cnblogs.com/znk97/p/14021279.html