您的位置:首页 > 其它

HDU 2222 Keywords Search(AC自动机)

2015-12-21 22:52 357 查看
传送门

AC自动机入门好题。作为模板的检测题吧。

AC自动机构造方法:

插入模式串,建成Trie,如果对于某个点x的next[c]不存在的话,就把next[c]指向fail[x]的next[c]

在Trie上加入失配边,就成功啦。

查找的时候一直按着next信息走到下一个节点。

代码:

#include<stdio.h>
#include<cstring>
#define MAXN 1000005
#define MAXC 26
#define MAXM 10005
#define MAXL 55
int n, root, sz, q[MAXM*MAXL];
char s[MAXN];
struct Trie {
int nxt[MAXC], fail, ed;
} t[MAXM * MAXL];
int NewNode() {
++ sz;
memset(t[sz].nxt, 0, sizeof t[sz].nxt);
t[sz].ed = 0;
return sz;
}
void Ins(char *s) {
int len = strlen(s), cur = root;
for(int i = 0; i < len; ++ i) {
if(!t[cur].nxt[s[i]-'a']) t[cur].nxt[s[i]-'a'] = NewNode();
cur = t[cur].nxt[s[i]-'a'];
}
++ t[cur].ed;
}
void Build() {
int l = 1, r = 0; t[root].ed = -1;
for(int i = 0; i < MAXC; ++ i)
if(!t[root].nxt[i]) t[root].nxt[i] = root;
else {
t[ t[root].nxt[i] ].fail = root;
q[++ r] = t[root].nxt[i];
}
while(l <= r) {
int u = q[l ++];
for(int i = 0; i < MAXC; ++ i)
if(!t[u].nxt[i]) t[u].nxt[i] = t[ t[u].fail ].nxt[i];
else {
t[ t[u].nxt[i] ].fail = t[ t[u].fail ].nxt[i];
q[++ r] = t[u].nxt[i];
}
}
}
int Query(char *s) {
int len = strlen(s), cur = root, ans = 0;
for(int i = 0; i < len; ++ i) {
cur = t[cur].nxt[s[i]-'a'];
int tmp = cur;
while(~t[tmp].ed) {
ans += t[tmp].ed;
t[tmp].ed = -1;
tmp = t[tmp].fail;
}
}
return ans;
}
int main() {
int T;
scanf("%d", &T);
while(T --) {
sz = 0; root = NewNode();
scanf("%d", &n);
for(int i = 1; i <= n; ++ i) {
scanf("%s", s);
Ins(s);
}
Build();
scanf("%s", s);
printf("%d\n", Query(s));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: