KMP算法

网上已经有大量关于KMP的博客了,我也写不出新意来,这里就不写KMP的原理,需要的可以去看看其他博客,这里主要聚焦一个问题:如何在知道KMP的原理后,快速写出代码?

对于KMP算法,我觉得应该牢记以下几条内容,以便能够快速写出代码:

  • 失配时,文本串不回溯,模式串回溯
  • 模式串回溯时依赖 next 数组
  • next 数组的计算只依赖模式串
  • 假设模式串为P,已知 next[i] = k 的情况下,求 next[i + 1] 的方法:若 P[i] == P[k],则 next[i + 1] = k + 1,否则视模式串在 P[k] 处失配,此时可以将 P[i] 理解为文本串当前正在匹配的字符,在这种情况下,应该将文本串的 P[i] 与模式串的 P[next[k]] 进行比较,若 P[i] == P[next[k]],则 next[i + 1] = next[k] + 1,否则重复上面的过程,让 P[i] 与 P[next[next[k]]] 进行比较,直到找到符合条件的 next 数组项,若 next 数组中不存在使得上述等式成立的项,则让 next[i + 1] 等于模式串中第一个元素的下标。

总之,通过迭代的方式可以求出 next 数组,下面是求 next 数组的示例,欢迎指正:

vector<int> generate_next(string pattern) 
{
    int i = 0, k = 0, n = pattern.size();
    vector<int> next(n);
    
    next[0] = -1;
    for (i = 1; i < n; ++i) {
        k = next[i - 1];
        while (k != -1) {
            if (pattern[k] == pattern[i - 1]) {
		break;
	    }
	    k = next[k];
	}	
	next[i] = k + 1; 
    }

    return next;
}

字符串匹配示例:

int find_string(string text, string pattern) 
{
    vector<int> next = generate_next(pattern);	
    int i = 0, j = 0, k = 0, n = text.size(), m = pattern.size();

    for (i = 0; i < n; ++i) {
	if (text[i] == pattern[j]) {
	    ++j;
	    if (j == m) {
                return i - m + 1;
	    }
	    continue;
	}

	k = next[j];
	while (k != -1) {
	    if (text[i] == pattern[k]) {
		break;
	    }
	    k = next[k];
	}
	j = k + 1;
    }  
	
    return -1;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值