#include<iostream>
#include<cstring>
#include<queue>
#include<map>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxn = 128;
char ss[10000+maxn];
int vis[501];
struct Node
{
Node *next[maxn];
Node *pre;//前缀指针
int last,id;
Node ()//初始化数据
{
memset(next, 0, sizeof (next));
pre =NULL, last = 0,id=0;
}
};
Node *root;
void Init ()
{
root = new Node;
}
void Insert (char *s,int id)
{
if (!s[0]) return ;
Node *p = root;
for (int i = 0; s[i]; i++)
{
int k=s[i]-' ';
if (!p -> next[k])
p -> next[k] = new Node;
p = p -> next[k];
}
p -> last++;//记录该节点单词总共插入的次数
p->id=id;
}
void Build ()//建立前缀指针
{
queue <Node*> qu;
for (int i = 0; i < maxn; i++)
if (root -> next[i])
{
root -> next[i] -> pre = root;
qu.push (root -> next[i]);//层次遍历建立前缀指针
}
while (!qu.empty ())
{
Node *temp = qu.front (); qu.pop ();
for (int i = 0; i < maxn; i++)
{
Node *pp = temp -> next[i];
if (pp)
{
Node *par = temp -> pre;
do
{
if (par -> next[i])
{
pp -> pre = par -> next[i];
break;
}
else
par = par -> pre;
} while (par);
if (!par)
pp -> pre = root;
qu.push (pp);//继续层次遍历建立前缀指针
}
}
}
}
int Query(char *s)
{
if (!s[0]) return 0;
Node *p = root;
int cnt = 0;
for (int i = 0; s[i]; i++)
{
int k=s[i]-' ';
while (p != root && !p -> next[k])
p = p -> pre;
p = p -> next[k];//现在所在位置为父节点,需要向下移动一个位置
if (!p)
p = root;//若匹配失败,移到根节点重新匹配
Node *pp = p;
while (pp != root && pp -> last != -1)//若匹配成功,last>0,代表该节点的单词数量,
{ //否则表示该节点没有单词
if(pp->last>0)
{
cnt+=pp->last;//统计该单词出现的次数
vis[pp->id]=1;
}
// pp -> last = -1;//可以重复查找,故不能置为-1
pp = pp -> pre;//继续判断整条链上的情况
}
}
return cnt;
}
void DelTree (Node *s)
{
if (!s) return ;
for (int i = 0; i < maxn; i++)
{
if (s -> next[i])
DelTree (s -> next[i]);
}
delete s;
}
int main()
{
int n;
scanf ("%d",&n);
Init ();
for (int i = 1; i <= n; i++)
{
scanf ("%s", ss);
Insert (ss,i);
}
getchar();
Build ();
int m;
scanf("%d",&m);
int total=0;
for(int i=1;i<=m;i++)
{
memset(vis,0,sizeof(vis));
scanf ("%s", ss);
int tmp=Query(ss);
getchar();
if(tmp)
{
printf("web %d:",i);
for(int j=1;j<=n;j++)
{
if(vis[j]) cout<<' '<<j;
}
cout<<endl;
total++;
}
}
DelTree (root);
printf("total: %d\n",total);
return 0;
}
hdu2896(病毒侵袭)
最新推荐文章于 2020-09-14 19:28:55 发布