串的模式匹配
给定一个主串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));
}