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;
}
此外还有一点要注意:因为查询串中有不是大写字母的字符,所以特判之后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;
}
相关文章推荐
- HDU 3065 病毒侵袭持续中(AC自动机模板)
- HDU 3065 病毒侵袭持续中(AC自动机 数组模板)
- HDU 3065 AC自动机模板题
- HDU 3065 病毒侵袭持续中(AC自动机(每个模式串出现次数))
- hdu 3065 病毒侵袭持续中 AC自动机模板题 ,,一A。
- AC自动机 ( 模板题啊 )——病毒侵袭持续中 ( HDU 3065 )
- hdu 3065 病毒侵袭持续中 ac自动机模板题
- [HDU 3065]病毒侵袭持续中[AC自动机][模板题]
- hdu 3065 病毒侵袭持续中(ac自动机模板题)
- hdu 2896 病毒侵袭 ac自动机模板题
- hdu 3065 AC自动机模版题
- [hdu 3065] 病毒侵袭持续中 [AC自动机] [病毒特征码匹配]
- hdu 2222 ac自动机更新模板 for onSite contest
- HDU 3065 AC自动机
- hdu 2222 keywords search (AC自动机 模板)
- HDU2222 AC自动机模板
- HDU 3065:病毒侵袭持续中(AC自动机)
- HDU-3065 病毒侵袭持续中 AC自动机
- AC自动机入门题目(HDU - 2222 )+模板+解释
- HDU 3065 病毒侵袭持续中 AC自动机