您的位置:首页 > 其它

AC自动机模板

2016-02-03 22:51 344 查看
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int maxn = 1000000 + 7;
const int type = 26;
struct node {
node *next[type];
node *fail;
int cnt;
};
node *q[maxn];
char ke[1000];
char str[maxn];
node *root;
int n, T;
int head, tail;

void insert(char *s, node *root) {
int len = strlen(s);
node *p = root, *t;
for(int i = 0; i < len; ++i) {
int id = s[i] - 'a';
if(p->next[id] == NULL) {
t = (node *)malloc(sizeof(node));
for(int j = 0; j < 26; ++j) t->next[j] = 0;
t->cnt = 0;
t->fail = 0;
p->next[id] = t;
}
p = p->next[id];
}
p->cnt ++;
}

void buildACnode(node *root) {
head = 0, tail = 1;
q[head] = root;
node *p, *t;
while(head < tail) {
//cout << head << " " << tail << endl;
t = q[head++];
for(int i = 0; i < 26; ++i) {
if(t->next[i]) {
if(t == root) t->next[i]->fail = root;
else {
p = t->fail;
while(p) {
//cout << "+";
if(p->next[i]) {
t->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(!p) t->next[i]->fail = root;
}
q[tail++] = t->next[i];
}
}
}
return ;
}

int query(node *root)
{
int cnt = 0, len = strlen(str);
node *p = root;
for(int i = 0; i < len; ++i) {
int id = str[i] - 'a';
while(!p->next[id] && p != root) p = p->fail;
p = p->next[id];
if(!p) p = root;
node *t = p;
while(t != root) {
if(t->cnt >= 0) {
cnt += t->cnt;
t->cnt = -1;
} else break;
t = t->fail;
}
}
return cnt;
}

void Delete(node *s)
{
for(int i = 0; i < 26; ++i)
if(s->next[i]) Delete(s->next[i]);
delete s;
}

int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
getchar();
root = (node *)malloc(sizeof(node));
for(int i = 0; i < 26; ++i) root->next[i] = 0;
root->fail = 0;
root->cnt = 0;
for(int i = 0; i < n; ++i) {
scanf("%s", ke);
insert(ke, root);
}
buildACnode(root);
scanf("%s", str);
int ans = query(root);
printf("%d\n", ans);
Delete(root);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: