浅谈KMP算法

上一篇博客写到,如果我们想要在主串中寻找相对应的子串序列,我们可以利用BF算法进行查找,不过那种查找方式效率实在是太低了,因此就有了编程界的三位大神 一同发明了KMP算法,这个算法是基于BF算法的,不过多了一个NEXT 数组,这是一个智能的数组,它能够在 子串与主串 匹配失败的时候 指导 子串应该 如何开始继续和主串匹配,而主串就不用回溯到之前的位置。
这个算法呢,最关键的是 大名鼎鼎的next 数组了 ,就是因为有了这个数组 ,这个算法才备受青睐! 客观上,next 数组 主要是看 不匹配 字符 发生的位置前 有多少个 前缀 和后缀 相等,如果没有 就填1 ,如果有一对,就填2,如果有两对,就填3 ,有三对就 填4 …… 以此类推。
那么,如何来推出这个 next数组呢?
大话数据结构是这样解释的:
在这里插入图片描述
在这里插入图片描述
不难以理解把 ? 但这都是 从肉眼识别的对吧,机器又不会啊,那该怎么办呢? 到代码里一探究竟吧。
利用KMP 算法 搜索子字符串的具体代码如下:

#include<stdio.h>
#include<string.h>
char zhu[250];
char zi[100];
int next1[100];// next数组长度为100 
next1[1]=0;//规定 next 1[1]为 0 
void next ( char *next ,int length)//实现 next数组的赋值 
{  	int i =1; //后缀下标 
	int j=0;//前缀下标 
	// 书中都是规定 主串 ,子串, next  数组 不存放任何数据的  所以要从1存放数据 
	while(i< length)
	{
	if(j==0||next1 [i]==next1 [j])//J =0是必须的,因为J可能根据next数组变成了0  
	{
	  i++; 
	  j++;
	  next1 [i]=j;//其实 这个思想主要是这样的: 通过next 不断 回到前面  直到前面和后面都有对应的值相等
	  //然后 就让 J+1移一个位置 然后 把值 付给next  而next 对应 值的位置 就是下一次开始比较的下标!,然后又找后面是否有 相同的以此类推!
	  //如果不动笔 写流程的话 ,可能这两部 实在难以理解,不过写下来就很好理解啦 ,推荐 字符串:abcabx 
	  
	}
	else 
	{
	 j=	next1[j];
	}	
	}
	printf("next 数组的各项元素为:"); 
	for(i=1;i<length;i++)
	{
		printf("%d",next1[i]);
		
	} printf("\n");
	
}
void  KMP(char * zhu, char *zi, int &index ,int zhulength,int zilength)
{ int i =1;
  int j =1;
  while(i<zhulength&&j<zilength)
  {
  	if(j==0||zhu[i]==zi[j]) //KMP 实现和BF 实现类似不同的就是失败的   时候需要用next数组进行指引 下一步怎么做
	   
  	{
	  	i++;
	  	j++;
	  }
	  else 
	  {
  		j=next1[j];//指导 J要从第几位 开始和 主串的 第I 位进行比较 
  	}
  	index=i-j+1;
  	if(j>=zilength)
  	
 	{
	 	printf("主串中从第: %d个元素开始匹配\n",index);
	 }
	 if(i>zhulength)
	 {
 		
		printf("主串中没有对应的子字符串序列\n");
 	}
  }
	
}

int main()
{  printf("请输入主字符串\n");
 char ch;
 int i =1;
 int zhulength =1;//长度都是从1开始的,因为 0 规定不存 数据  
 int zilength=1;
 
 ch=getchar();
  while (ch!='\n')
  {
  	zhu[i++]=ch;
  	ch=getchar();
  	zhulength++;
  	
  }
  
   printf("请输入子字符串\n");
   
  	ch=getchar();
  	int j =1;
  	while(ch!='\n')
  	{
	  	zi[j++]=ch;
	  ch=getchar();
	  zilength++; 	
     }
    next(zi,zilength);
     int index;
     KMP(zhu,zi,index,zhulength,zilength);
   return 0;
 

想要好好理解这个 next数组怎么来的 记得写流程哦~ 如果有人好奇为什么这个next数组能够正确的指导 子串 下一次 比较的位置,博主也不该清楚,查阅网上一些资料,好像是通过while 实现递归思想… 汗,之前博主就说过了,请不要试图了解 递归的过程 ,因为很绕…(的确是我现在能力不够)
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是牛大春呀

老板糊涂啊

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值