ac自动机模板题
下面说几个注意点:
1、题目中说字符是可见字符,可见字符的asc码是32--127 ,由于不清楚这一点wa了无数次
下面说几个注意点:
1、题目中说字符是可见字符,可见字符的asc码是32--127 ,由于不清楚这一点wa了无数次
2、发现AC自动机网上代码都是用指针来写的,我这里提供静态数组的写法
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define N 60005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
int f[N],last[N],vis[N];
int flag;
struct Trie
{
int ch[N][128];
int val[N];
int sz;
void init()
{
memset(ch,0,sizeof(ch));
memset(val,0,sizeof(val));
memset(f,0,sizeof(f));
memset(last,0,sizeof(last));
sz = 1;
}
void insert(char* s,int v)
{
int u = 0;
int i,len = strlen(s);
for(i = 0; i < len; i++)
{
int c = s[i] - ' ';
if(!ch[u][c])
ch[u][c] = sz++;
u = ch[u][c];
}
val[u] = v;
}
void GetFail()
{
queue<int> q;
f[0] = 0;
int i;
for(i = 0; i < 128; i++)
{
int u = ch[0][i];
if(u)
{
q.push(u);
f[u] = 0;
last[u] = 0;
}
}
while(!q.empty())
{
int r = q.front();
q.pop();
for(i = 0; i < 128; i++)
{
int u = ch[r][i];
if(!u) continue;
q.push(u);
int v = f[r];
while(v && !ch[v][i])
v = f[v];
f[u] = ch[v][i];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
}
void print(int j)
{
if(j)
{
flag = 1;
vis[val[j]] = 1;
print(last[j]);
}
}
void find(char *T)
{
int n = strlen(T);
int j = 0;
for(int i = 0; i < n; i++)
{
int c = T[i] - ' ';
while(j && !ch[j][c])
j = f[j];
j = ch[j][c];
if(val[j]) print(j);
else if(last[j]) print(last[j]);
}
}
}trie;
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int n,j,i;
char str[10005];
while(scanf("%d",&n) != EOF)
{
trie.init();
for(i = 1; i <= n; i++)
{
scanf("%s",str);
trie.insert(str,i);
}
trie.GetFail();
int m,ans = 0;
scanf("%d",&m);
for(i = 1; i <= m; i++)
{
scanf("%s",str);
flag = 0;
memset(vis,0,sizeof(vis));
trie.find(str);
if(flag)
{
ans++;
printf("web %d:",i);
for(j = 1; j <= n; j++)
if(vis[j])
printf(" %d",j);
printf("\n");
}
}
printf("total: %d\n",ans);
}
return 0;
}