标签:
1 5 she he say shr her yasherhs
3
#include <cstdio>
#include <cstring>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=1000010;
const int bsz=26;
typedef long long ll;
char txt[1000010];
bool vis[510];
int ans;
struct Trie
{
int ch[maxn][bsz],val[maxn],sz,cnt[maxn]; // ch存Trie val-节点对应的单词 cnt-节点结尾单词个数
int f[maxn],last[maxn];//f-失配指针 last-后缀链接
int newnode()
{
val[sz]=0; cnt[sz]=0;
memset(ch[sz],-1,sizeof ch[sz]);
return sz++;
}
void init()
{
sz=0;
newnode();
}
int idx(char c) // 取c的标号 具体看字符为什么
{
return c-'a';
}
void Insert(char *st,int id)
{
int u=0,n=strlen(st),c,i;
for(i=0;i<n;i++)
{
c=idx(st[i]);
if(ch[u][c]==-1)
ch[u][c]=newnode();
u=ch[u][c];
}
val[u]=id;
cnt[u]++;
}
void build()
{
int u=0,v,i;
queue<int> q;
f[0]=0;
for(i=0;i<bsz;i++)
{
v=ch[u][i];
if(v==-1) ch[u][i]=0;
else
{
f[v]=0;
q.push(v);
}
}
while(!q.empty())
{
u=q.front();
q.pop();
last[u]=val[f[u]]?f[u]:last[f[u]];
for(i=0;i<bsz;i++)
{
v=ch[u][i];
if(v==-1) ch[u][i]=ch[f[u]][i]; // 将NULL变为有意义 沿着父亲失配指针走第一个有意义的节点
else
{
f[v]=ch[f[u]][i];
q.push(v);
}
}
}
}
bool Find(char *st,int m,int id)
{
int n=strlen(st),i,u=0,c,p,flag=0;
//memset(vis,0,sizeof vis); 可标记哪些单词出现过 同样的单词只标记一个
for(i=0;i<n;i++)
{
c=idx(st[i]);
u=ch[u][c];
p=val[u]?u:last[u];
while(p)
{
//vis[val[p]]=true;
if(val[p]){ ans+=cnt[p]; cnt[p]=0; } // 加上该串出现次数 清零 避免重复计数
flag=1;
p=last[p];
}
}
if(!flag) return false;
// for(i=1;i<=m;i++)
// if(vis[i])
// printf(" %d",i);
// putchar('\n');
return true;
}
} ac;
int main()
{
int i,n,m,tot;
scanf("%d",&tot);
while(tot--)
{
scanf("%d",&n);
ac.init();
for(i=1;i<=n;i++)
{
scanf("%s",txt);
ac.Insert(txt,i);
}
ac.build();
ans=0;
scanf("%s",txt);
ac.Find(txt,n,i);
printf("%d\n",ans);
}
return 0;
}
/*
1
5
she
he
say
her
her
yasherhs
*/
hdu 2222 Keywords Search(AC自动机入门)
标签:
原文地址:http://blog.csdn.net/tobewhatyouwanttobe/article/details/46405065