KMP算法(c++实现)

/**
 * 算法名称:KMP
 * 算法目的:给出字符串str,和模式串ptr,要求找出str中ptr的匹配位置和个数
 * 算法思想:
 *     1、定义k为模式串失配位置j的前j-1长度子串的最大相等前后缀长度,(比如abcab最大前后缀长度为2)
 *     2、当模式串在j位置失配时,模式串相对字符串str向后移动(子串长度-k)个位置(因为k为前j-1子串的最大前后缀长度,
 *	   前后缀相等,那么j失配,前j-1串的后缀和前缀已经匹配,所以不用再比较了),以减少暴力求解时的比较次数。
 */
/**
 * 计算next数组
 * @param ptr 模式串
 * @param next next数组
 * @param len  模式串长度
 */
void calc_next(const char *ptr, int *next, const int len)
{
    next[0] = 0; // next[0]初始化为0,0表示不存在相同的最大前缀和最大后缀
    int p = 0; // p初始化为0,p为头部比较指针
    for (int i = 1; i < len; i++) // 从1开始,避免一个字符时与自身相等
    {
        while (p > 0 && ptr[p] != ptr[i]) p = next[p]; // 如果下一个不同,那么p就变成next[p]往前回溯,注意next[p]是小于p的,无论p取任何值。
        if (ptr[p] == ptr[i]) p++; // 如果相同,p++
        next[i] = p;//这个是把算的p的值(就是相同的最大前缀和最大后缀长)赋给next[i]
    }
}

/**
 * KMP,单模式串匹配
 * @param str 目标字符串
 * @param slen 目标字符串长度
 * @param ptr 模式串
 * @param plen 模式串长度
 * @param match 记录匹配的首字符下标
 * @return 匹配到的个数
 */
int KMP(const char *str, const int slen, const char *ptr, const int plen, int **match)
{
	*match = new int[plen]; // 保存匹配的首字符下标
	int cnt = 0;
    int *next = new int[plen];
    calc_next(ptr, next, plen); // 计算next数组
	int p = 0;
	for (int i = 0; i < slen; i++) 
	{
		while (p > 0 && ptr[p] != str[i]) p = next[p]; // ptr与str有部分匹配
		if (ptr[p] == str[i]) p++;
		if (p == plen) 
		{
			(*match)[cnt++] = i - plen + 1;
			p = next[p - 1];
		}
	}
	return cnt;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值