KMP算法

  1. 前缀和后缀的概念(以aabaa为例)
    所有的前缀和后缀如下
    在这里插入图片描述

下面详细说next数组(next[i]表示p[0]-p[i]串的最大相同前后缀长度)的求法,可以看成是一个动态规划的过程。
首先,next[0] = 0(前缀和后缀不能是字符串本身)。
现在要求next[i],首先需要前i个字符的最大相同前后缀长度j(也就是next[i-1]),然后判断p[j](下表中Z)与p[i](下表中Y)是否相同,相同则next[i] = j+1。
字符串如下
在这里插入图片描述

若Z!=Y。
在这里插入图片描述
那么就要求出最大的j’如上,使得p1前j’个字符和p2后j’个字符完全相同,然后p1==p2,也就是最大的j’使得p1前j’个字符和p1后j’个字符完全相同,那么j’也就是next[j-1]的含义(j’==next[j-1]),因此下一次比较也就是p[j’]与p[i],若相同则next[i] = j’+1,若不相同则p1’和p2’作为新的p1和p2继续进行上述操作,直到j’ = 0,此时若p[0]==p[i]则next[i] = 1,否则next[i] = 0。

下面是代码

#include<iostream>
#include<string>
#include<vector>
using namespace std;

// next数组 next[i]表示p串的相同前后缀最大长度
// next[j-1] 也可以看做是 p[j]和s[i]匹配不上,p下一个需要跳转的字符位置
// 求next数组可以看成是一个动态规划的过程

int main(int argc, char const *argv[])
{
	string s = "aabbaabbaabbaafwe";
	string p = "aabbaaf";
	vector<int> next(p.size(),0);
	for (int i = 1;i<p.size();++i){
	    int j = next[i-1];
		while(j>0&&p[i]!=p[j]){
			j = next[j-1];
		}
		if(p[i]==p[j]){//不相等则说明j==0
			j++;
		}
		next[i] = j;
	}
	i = 0,j = 0;
	while(i<s.size()&&j<p.size()){
		while(j>0&&p[j]!=s[i]){
			j = next[j-1];
		}
		if (p[j]==s[i]){
			j++;
			i++;
		}
		else{//其实也就是j == 0的情况 并且s[i]!=p[0],只有i指针后移。
			i++;
		}
	}
	if (j == p.size()) cout<<"match"<<endl;
	else cout<<"not match"<<endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值