您的位置:首页 > 其它

hdu4763 KMP

2015-08-11 09:24 471 查看
稀里糊涂1A开心。我做了2次kmp,先第一次利用next[],由于next[]前面一小段一直是一样的,所以可以根据这个来找。然后就找到了开头和结尾,还缺中间的部分。

中间的部分就是通过开头部分去模式匹配,如果有就直接输出,break就可以。(因为开始长度最长)

#include<stdio.h>
#include<string.h>
#define maxn 1000010
int next[maxn],nexts1[maxn];
char s[maxn],s1[maxn],s2[maxn],flag;
void getnext()
{
int j,k,len=strlen(s);
j=0;
k=-1;
next[0]=-1;
while(j<len)
{
if(k==-1||s[j]==s[k])
{
j++;
k++;
next[j]=k;
}
else k=next[k];
}
}
int KMP()
{
int i,j,k,len=strlen(s1);
k=-1;
j=0;
nexts1[0]=-1;
while(j<len)
{
if(k==-1||s1[j]==s1[k])
{
j++;
k++;
nexts1[j]=k;
}
else k=nexts1[k];
}
j=0;
i=0;
int fl=strlen(s2);
while(i<fl)
{
if(j==-1||s1[j]==s2[i])
{
i++;
j++;
}
else
j=nexts1[j];
if(j==strlen(s1))
{
return 1;
}
}
return 0;
}
void kmp()
{
int i,j,len=strlen(s),ans;
getnext();
i=len-1;
while(next[i]!=-1)
{
int k=0,p=0;
flag=1;
if(s[next[i]]!=s[i])//这里我是这样想的 如果当前的和他next[]的值不一样,那就要继续往下找
i=next[i];

for(j=0;j<=next[i];j++)
s1[k++]=s[j];
s1[k]='\0';
if(s1[0]=='\0')
{
flag=0;
break;
}
for(j=next[i]+1;j<len-1-next[i];j++)
s2[p++]=s[j];
s2[p]='\0';

if(!KMP())
{
flag=0;
}
else
{
ans=strlen(s1);
break;
}
i=next[i];
//printf("%s   %s\n",s1,s2);
}
if(flag==0)
{
printf("0\n");
}
else
printf("%d\n",ans);
}
int main()
{
int i,j,t;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
if(strlen(s)<3)
{
printf("0\n");
continue;
}
kmp();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: