本题需要注意几个方面:
1、字符的范围是可见的ASCLL码字符,数组要开到127。
2、虽然题目的数据弱了,但是自己要考虑的周全。
数据一:
2 sher he 2 she sher答案:
web 1: 2 web 2: 1 2 total: 2数据二:
2 a aa 1 aaaa答案:
web 1: 1 2 total: 1
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
struct trie
{
int mark;
trie *fail;
trie *next[130];
trie()
{
mark=0;
fail=NULL;
memset(next,0,sizeof(next));
}
};
trie *root;
void init(char *v,int id)
{
int i;
trie *p=root;
for(i=0; v[i]; i++)
{
int tep=v[i];
if(p->next[tep]==NULL) p->next[tep]=new trie();
p=p->next[tep];
}
p->mark=id;
}
void getac()
{
queue<trie*>q;
q.push(root);
while(!q.empty())
{
int i;
trie *p,*tep;
p=q.front();
q.pop();
for(i=0; i<128; i++)
{
if(p->next[i]!=NULL)
{
if(p==root) p->next[i]->fail=root;
else
{
tep=p->fail;
while(tep!=NULL)
{
if(tep->next[i]!=NULL)
{
p->next[i]->fail=tep->next[i];
break;
}
tep=tep->fail;
}
if(tep==NULL) p->next[i]->fail=root;
}
q.push(p->next[i]);
}
}
}
}
int finde(char *v,int *ans)
{
int i,k=0;
trie *p=root,*q;
for(i=0; v[i]; i++)
{
int tep=v[i];
while(p->next[tep]==NULL && p!=root)
p=p->fail;
p=p->next[tep];
if(p==NULL) p=root;
q=p;
while(q!=root) //把每个都匹配过去,因为题目说了最多只有三种不同的!
{
if(q->mark!=0) ans[k++]=q->mark;
q=q->fail;
}
}
return k;
}
void del(trie *p)
{
for(int j=0; j<26; j++) if(p->next[j]!=NULL) del(p->next[j]);
free(p);
}
int main()
{
int n,m;
while(scanf("%d",&n)!=-1)
{
int i,j;
root=new trie();
getchar();
for(i=1; i<=n; i++)
{
char v[202];
gets(v);
init(v,i);
}
getac();
scanf("%d",&m);
getchar();
int cont=0;
for(i=1; i<=m; i++)
{
char x[10005];
int ans[10];
memset(ans,0,sizeof(ans));
gets(x);
int k=finde(x,ans);
if(k)
{
printf("web %d:",i);
sort(ans,ans+k);
for(j=0; j<k; j++)
{
if(ans[j]!=ans[j+1]) printf(" %d",ans[j]); //为了去重
}
puts("");
cont++;
}
}
printf("total: %d\n",cont);
del(root);
}
}