题意:给出n个字符串,问这n个串中是否存在一个字符串满足其他n-1个字符串是它的子串
思路:
1.满足条件的串一定是n个串中长度最长的
2.多个模式串T是否是主串S的子串(多模式串匹配),而AC自动机就是用来处理多模式串的问题
代码:
#include<stdio.h>
#include<string.h>
#define MAX 100005
int ans,cnt,next[MAX],ch[MAX][30],bo[MAX],que[MAX];
void make(char *s)
{
int u=1,len=strlen(s),i,temp;
for(i=0;i<len;i++)
{
temp=s[i]-'a';
if(!ch[u][temp])
{
ch[u][temp]=++cnt;
memset(ch[cnt],0,sizeof(ch[cnt]));
}
u=ch[u][temp];
}
bo[u]++;
return ;
}
void bfs()
{
int i,j,k,u,v;
for(i=0;i<=25;i++)
{
ch[0][i]=1;
}
que[1]=1; next[1]=0;
for(i=1,j=1;i<=j;i++)
{
u=que[i];
for(k=0;k<=25;k++)
{
if(!ch[u][k])
ch[u][k]=ch[next[u]][k];
else
{
que[++j]=ch[u][k];
v=next[u];
next[ch[u][k]]=ch[v][k];
}
}
}
}
void Find(char *s)
{
int u=1,len=strlen(s),temp,i,k;
for(i=0;i<len;i++)
{
temp=s[i]-'a';
k=ch[u][temp];
while(k>1)
{
ans+=bo[k];
bo[k]=0;
k=next[k];
}
u=ch[u][temp];
}
return ;
}
int main()
{
int T,n,i;
char s[MAX<<1];
scanf("%d",&T);
while(T--)
{
ans=0; cnt=1;
memset(bo,0,sizeof(bo));
for(i=0;i<=25;i++)
{
ch[0][i]=1;
ch[1][i]=0;
}
scanf("%d",&n);
int length=0;
int index;
char Temp[MAX];
for(i=1;i<=n;i++)
{
scanf("%s",s);
make(s);
int l=strlen(s);
if(l>length)
{
length=l;
index=i;
strcpy(Temp,s);
}
}
bfs();
Find(Temp);
if(ans==n)
printf("%s\n",Temp);
else
printf("No\n");
}
return 0;
}
博客围绕一个问题展开,即判断n个字符串中是否存在一个字符串,使其他n - 1个字符串是它的子串。思路指出满足条件的串是最长串,且该问题属于多模式串匹配,可使用AC自动机处理,并给出了代码思路。
449

被折叠的 条评论
为什么被折叠?



