码迷,mamicode.com
首页 > 其他好文 > 详细

字符串 KMP

时间:2020-11-26 14:31:26      阅读:4      评论:0      收藏:0      [点我收藏+]

标签:amp   int   ++   class   res   意义   else   集合   ret   

KMP

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;
}
*/

next数组

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

字符串 KMP

标签:amp   int   ++   class   res   意义   else   集合   ret   

原文地址:https://www.cnblogs.com/znk97/p/14021279.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!