AC自动机模板。学习的是学长的写法,感觉很好。
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 502;
const int MAX = 130;
char virus[205];
char web[10005];
int flag[1005][5];
struct Trie{
int next[MAX];
int fail;
int cnt;
void init()
{
memset(next, -1, sizeof(next));
fail = -1;
cnt = 0;
}
};
Trie trie[100002];
int sz;
void init()
{
sz = 1;
trie[0].init();
}
void myinsert(char* s, int tag)
{
int i = 0;
int p = 0;
while(s[i])
{
int ch = s[i];
if(trie[p].next[ch] == -1)
{
trie[sz].init();
trie[p].next[ch] = sz++;
}
p = trie[p].next[ch];
i++;
}
trie[p].cnt = tag;
}
void buildACautomachine()
{
int i, pre, pre_fail, child;
trie[0].fail = -1;
queue<int> que;
que.push(0);
while(!que.empty())
{
pre = que.front();
que.pop();
for(i = 0; i < MAX; i++)
{
if(trie[pre].next[i] != -1)
{
child = trie[pre].next[i];
pre_fail = trie[pre].fail;
while(pre_fail != -1)
{
if(trie[pre_fail].next[i] != -1)
{
trie[child].fail = trie[pre_fail].next[i];
break;
}
pre_fail = trie[pre_fail].fail;
}
if(pre_fail == -1)
trie[child].fail = 0;
que.push(child);
}
}
}
}
int query(char* s, int t)
{
int i = 0, cnt = 0, p = 0, tmp;
int k = 0;
while(s[i])
{
int ch = s[i];
while(trie[p].next[ch] == -1 && p != 0)
p = trie[p].fail;
p = trie[p].next[ch];
tmp = p = (p == -1?0:p);
while(tmp != 0 && trie[tmp].cnt != -1)
{
if(trie[tmp].cnt != 0)
flag[t][k++] = trie[tmp].cnt;
tmp = trie[tmp].fail;
}
i++;
}
return k;
}
int main()
{
int n, m;
while(~scanf("%d", &n))
{
init();
memset(flag, 0, sizeof(flag));
for(int i = 0; i < n; i++){
scanf("%s", virus);
myinsert(virus, i+1);
}
buildACautomachine();
scanf("%d", &m);
int tot = 0;
for(int i = 0; i < m; i++){
scanf("%s", web);
int num;
if(num = query(web, i))
{
tot++;
sort(flag[i], flag[i] + num);
printf("web %d:", i + 1);
for(int j = 0; j < num; j++)
printf(" %d", flag[i][j]);
puts("");
}
}
printf("total: %d\n", tot);
}
return 0;
}
/*
3
aaa
bbb
ccc
2
aaabbbccc
bbaacc
*/