KMP学习心得

嗯。。。我不会讲什么原理之类的 我只会讲一下自己搞了很久才明白的地方

1.关于j的通俗定义

j是一个指针 相当于当前i对应的s1在s2里面的位置 若根本就没有一个相同的字符那就是0

2.关于next数组的通俗理解

对于s2的一个字母s next[s]相当于s所在的字符串(这个字符串从s向后延伸 长度不定 且这个字符串等于整个字符串的前缀)在整个字符串从前往后的第一个位置

3.关于每次j怎么变化

若j的下一个指向的这个字母与i的不相同 那相当于要把整个s2字符串往右移 相当于就是把j移到next[j]的位置(这看似往前移了 实质上把j往左移是把整个s2往后移)

4.j的边界

当j等于0 说明之前的j指向的那个字母是无法找到一个串与这个串紧接着的前面的那一坨里的一个前缀相等 所以我们只有把i往右移

#include<bits/stdc++.h>
using namespace std;	
char s1[1000005],s2[1000005];
int next[1000005];
int len1,len2;
inline void getnext()
{
	int j=0;
	for(int i=2;i<=len2;i++)
    {     
       while(j&&s2[i]!=s2[j+1])	j=next[j];	//此处判断j是否为0的原因在于,如果回跳到第一个字符就不用再回跳了 
       if(s2[j+1]==s2[i])	j++;    
       next[i]=j; 
    }
}


int kmp()
{
	int i=0,j=0,f=0;
	for(int i=1;i<=len1;i++)
	{
		while(j>0&&s2[j+1]!=s1[i])
		{
			j=next[j];
		}
		if(s2[j+1]==s1[i])	j++;
		if(j==len2)
		{
			f=1;
			cout<<i-len2+1<<endl;
		//	j=next[j];
		}
	}
	return f;
}
int main()
{
	scanf("%s",s1+1);
	scanf("%s",s2+1);
	len1=strlen(s1+1);
	len2=strlen(s2+1);
	getnext();
	if(kmp()!=1)	cout<<"NO"<<endl; 
	/*for(int i=1;i<=len2;i++)
	{
		cout<<next[i]<<" ";
	}*/
	return 0;
}									


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值