重启c语言之串——串的模式匹配

串的模式匹配

给定一个主串S(长度<=10^6)和一个模式串T(在长度<=10的五次幂),要求在主串S中找出与模式T相匹配的子串,返回相匹配的子串中的第一个字符在主串S中出现的位置。

输入格式:
输入有两行: 第一行是主串S; 第二行是模式T.

输出格式:
输出相匹配的子串中的第一个字符在主串S中出现的位置。若匹配失败,输出0.

输入样例:
在这里给出一组输入。例如:

aaaaaba
ba

输出样例:
在这里给出相应的输出。例如:

6

思路:采用kmp算法进行匹配。以空间换取时间。具体的几个点在于next数组的求解、kmp算法。首先我们需要求出next数组,因为next数组中的值只和模式串有关,因此只需知道模式串的值即可得到对应的next数组的值。kmp算法就是模式匹配下的情况,整体的代码如下所示:

#include<stdio.h>
#include<string.h> 
#include<stdlib.h>
 int next[100001];
 void get_next(char*t,int*next)
 {
 	int i=0;//next数组的下标
	 int j=-1;//next的值
	 next[0] =-1;//防止进入死循环,而且到不能匹配时能整体后移
	 while(t[i]!='\0')
	 {
	 	if(j==-1||t[i]==t[j])  //j=-1进入这个循环是为了整体向后移;
	 	{
	 		//如果不存在或者条件符合,可得到next的值
			i++;j++;
			next[i]=j;
		 }
		 else
		 j=next[j];	 
	 }
 }
 int KMP(char*s,char*t,int pos)//pos为s串的起始比较位置 
 {
 	int j=0;
	 while(t[j++]!='\0');
	 int *next=(int*)malloc((j-1)*sizeof(int));
	 int length=j-1;//串的长度
	 //调用函数,生成对应的next值
	 get_next(t,next);
	 int i=pos-1;//主串起始位置
	 j=0;//模式串下标
	 while(s[i]!='\0'&&j<length)
	 {
	 	if(j==-1||s[i]==t[j])
	 	{
	 		i++;j++;
		 }
		 else
		 {
		 	j=next[j];//如果不等,则从next值开始下一次比较 
		 }
	  } 
	  if(t[j]=='\0'&&j!=-1)
	  return i-j+1;
	  else
	  return 0; 
  } 
 int main()
{
	char s[1000001],t[100001];
	int len;
	gets(s);
	gets(t);
	len=strlen(t);
	get_next(t,next);
    printf("%d",KMP(s,t,1));
 } 

猜你喜欢

转载自blog.csdn.net/weixin_43723423/article/details/106319573