KMP算法的简单实现(适合小白观看)。

【最浅显易懂的 KMP 算法讲解】https://www.bilibili.com/video/BV1AY4y157yL?vd_source=757e0fceb4526f3b51243a4422760ebe

下面代码结合上面视频(有动画展示)食用最宜;

代码根据上面视频整理所得,并加入非常多的注释。

#include <iostream>
using namespace std;
//Next数组第一个默认为零,prefix_len是公共子串长度,kmp_search函数之外,定义的i是主函数里指向子串的指针,j是Next数组的下标。 
int Next[111111]={0},prefix_len=0,i=1,j=1; 
//主串与子串。 
string s,s1;
int kmp_search(string s,string s1){
	int i=0,j=0;//i是主串中的指针,j是子串的指针,都是从零开始; 
	//lens是主串的长度,lens1是子串的长度; 
	int lens=(int)s.length();
	int lens1=(int)s1.length();
	//主串的指针i是一直往后移 ,不向前回溯的。 
	while(i<lens){
		//字符匹配,两个指针都往后移。 
		if(s[i]==s1[j]){
			i+=1;
			j+=1;
		}
		//字符匹配失败,根据之前求的Next数组 跳过子串前面的一些字符。 
		else if(j>0){
			j=Next[j-1];
		}
		//字符匹配不仅失败了,而且一开始就失败了,所以主串的指针向下一个移 
		else {
			i+=1;
		}
		//最后一个位置lens-1如果相同,j会加一,所以这里判断j是否与lens相等; 
		if(j==lens1){
			return i-j;
		}
	}
	//找不到返回-1; 
	return -1; 
}
int main(){
	//首先输入主串与子串。 
	cin>>s>>s1;
	//子串的长度 
	int len=(int)s1.length();
	//使用递推的方法来遍历子串求Next数组,此处最难理解; 
	while(i<len){
		//指针指向0时,没有子串,所以i初始值为1,Next数组第一个初始为零;
		//此处可以看做前缀与后缀比较 
		if(s1[prefix_len]==s1[i]){
			prefix_len+=1;
			Next[j++]=prefix_len;
			i+=1;
		}
		//如果下一个字符不匹配的话 下面的两种情况 
		else{
			//如果共同的字符串为零,直接赋值Next数组直接赋值为零 
			if(prefix_len==0){
				Next[j++]=0;
				i+=1;
			}
			//不是零的情况,就在相同子串中,查找更小的相同字串 
			//一直回溯,回溯到找到相同的字串,或者相同的字串长度为0,在上面if语句中结束本次回溯; 
			else {
				prefix_len=Next[prefix_len-1];
			}
		}
	}
	cout<<kmp_search(s,s1);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值