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

串的模式匹配 2

给定两个由英文字母组成的字符串 String 和 Pattern,要求找到 Pattern 在 String 中第一次出现的位置,并将此位置后的 String 的子串输出。如果找不到,则输出“Not Found”。

本题旨在测试各种不同的匹配算法在各种数据情况下的表现。各组测试数据特点如下:


数据0:小规模字符串,测试基本正确性;
数据1:随机数据,String 长度为 10^5,Pattern 长度为 10;
数据2:随机数据,String 长度为 10^5,Pattern 长度为 10^2;
数据3:随机数据,String 长度为 10^5,Pattern 长度为 10^3;
数据4:随机数据,String 长度为 10^5,Pattern 长度为 10^4;
数据5:String 长度为 10^6,Pattern 长度为 10^5;测试尾字符不匹配的情形;
数据6:String 长度为 10^6,Pattern 长度为 10^5;测试首字符不匹配的情形。

输入格式:
输入第一行给出 String,为由英文字母组成的、长度不超过 10^​6的字符串。第二行给出一个正整数 N(≤10),为待匹配的模式串的个数。随后 N 行,每行给出一个 Pattern,为由英文字母组成的、长度不超过 10的5次幂的字符串。每个字符串都非空,以回车结束。

输出格式:
对每个 Pattern,按照题面要求输出匹配结果。

输入样例:

abcabcabcabcacabxy
3
abcabcacab
cabcabcd
abcabcabcabcacabxyz

输出样例:

abcabcacabxy
Not Found
Not Found

思路:基本上对上一篇文章串的模式匹配的一个改进,上一篇文章中利用kmp算法求得了刚开始匹配的位置,因此,只要输出从该位置到字符串尾的值即可。若没有匹配则即位置为0时输出Not Found。但是我的代码对于前两个测试点总是出现运行时错误,虽然人家已经给出来了各个测试点的数据属性,但是我还是emm菜。还有就是对于样例,需要一步一步输入,不然也会出错,好在程序还是过了下面几个测试点
代码如下仅供参考:

#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));
 } 

在这里插入图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Allen吖

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值