您的位置:首页 > 其它

HDU 3065 病毒侵袭持续中(AC自动机模板)

2013-08-01 10:30 471 查看
这题太坑了...........wa了无数次才知道是多case

此外还有一点要注意:因为查询串中有不是大写字母的字符,所以特判之后conitnue,但此时应让p指向根结点,这也是没匹配的一种情况

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;

struct trie {
trie *next[26];
int flag;
char virus[55];
int num;
trie *fail;
trie() {
fail = NULL;
flag = 0;
num = 0;
memset(next,0,sizeof(next));
}
}*q[55555];

trie *rt = new trie();
int head,tail;
char keyword[1111][55];
char book[2111111];

void insert(char *key) {
trie *p = rt;
char tmp[55];
strcpy(tmp,key);
while(*key) {
int t = *key - 'A';
if(p->next[t] == NULL) p->next[t] = new trie();
p = p->next[t];
key ++;
}
p->flag = 1;
strcpy(p->virus,tmp);
}

void bfs() {
rt->fail = NULL;
head = tail = 0;
q[head++] = rt;
while(head != tail) {
trie *t = q[tail++];
trie *tmp = NULL;
for(int i=0; i<26; i++) {
if(t->next[i] != NULL) {
if(t == rt ) t->next[i]->fail = rt;
else {
tmp = t->fail; //沿着父亲的fail指针走
while(tmp != NULL) {
if(tmp->next[i] != NULL) {
t->next[i]->fail = tmp->next[i];
break;
}
tmp = tmp->fail;
}
if(tmp == NULL) t->next[i]->fail = rt;
}
q[head++] = t->next[i];
}
}
}
}

void query(char *key) {
trie *p = rt;
while(*key) {
int t = *key - 'A';
if(t < 0 || t >= 26) {
key ++;
p = rt; //相当于没找到匹配的,p应该指回rt
continue;
}
while(p != rt && p->next[t] == NULL) p = p->fail;
p = p->next[t];
if(p == NULL) p = rt;
trie *tmp = p;
while(tmp != rt && tmp->flag != 0) {
tmp->num++;
tmp = tmp->fail;
}
key++;
}
}

void search(char *key) {
trie *p = rt;
while(*key) {
int t = *key - 'A';
if(p->next[t] == NULL) return ;
p = p->next[t];
key++;
}
if(p->num != 0) {
printf("%s: %d\n",p->virus,p->num);
}
}

void free(trie *p) {
for(int i=0; i<26; i++) {
if(p->next[i] != NULL) free(p->next[i]);
}
delete p;
}
int main() {
int n;
while(cin >> n) {
getchar();
memset(q,0,sizeof(q));
rt = new trie();
for(int i=0; i<n; i++) {
gets(keyword[i]);
insert(keyword[i]);
}
bfs();
gets(book);
query(book);
for(int i=0; i<n; i++) {
search(keyword[i]);
}
free(rt);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: