您的位置:首页 > 其它

hdu 3065 病毒侵袭持续中 ac_automaton

2013-11-25 01:39 351 查看
用一个二维字符串数组存储,第i个病毒是什么,virus[i]代表的就是第i个病毒的数量,如果virus[i] != 0表明有这个病毒存在,printf( "%s: %d\n" ,s2[i], virus[i]);就是满足要求的输出。

#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;

const int MAXN = 50010;

struct Trie_Node
{
int id;
Trie_Node* fail;
Trie_Node* pNext[26];
Trie_Node()
{
id = 0;
fail = NULL;
memset(pNext, NULL, sizeof(pNext));
}
};

Trie_Node* proot;
Trie_Node* q[MAXN];
int head, tail;

int virus[1010];

void Insert_Trie(char* str, int id)
{
Trie_Node* p = proot;
for (; *str; str++)
{
int j = *str - 'A';
if(p->pNext[j] == NULL)
p->pNext[j] = new Trie_Node;
p = p->pNext[j];
}
p->id = id;
}

void Build_ac_automaton_fail()
{
head = tail = 0;
proot->fail = NULL;
q[tail++] = proot;
while (head != tail)
{
Trie_Node* temp = q[head++];
Trie_Node* p = NULL;
for(int i = 0; i < 26; ++i)
{
if (temp->pNext[i] != NULL)
{
if(temp == proot)
temp->pNext[i]->fail = proot;
else
{
p = temp->fail;
while (p != NULL)
{
if (p->pNext[i] != NULL)
{
temp->pNext[i]->fail = p->pNext[i];
break;
}
p = p->fail;
}
if(p == NULL)
temp->pNext[i] = proot;
}
q[tail++] = temp->pNext[i];
}
}
}
}

void Query_ac_automaton(char* str)
{
int i = 0;
Trie_Node* p = proot;
while (str[i])
{
if (!isupper(str[i]))
{
p = proot;
i++;
continue;
}
int j = str[i] - 'A';
while(p->pNext[j] == NULL && p != proot)
p = p->fail;
p = (p->pNext[j] == NULL) ? proot : p->pNext[j];
Trie_Node* temp = p;
while (temp != proot)
{
if(temp->id != 0)
virus[temp->id]++;
temp = temp->fail;
}
i++;
}
}

char s1[2000010], s2[1010][55];
int main()
{
int n;
int i;
while (~scanf("%d", &n))
{
proot = new Trie_Node;
for (i = 1; i <= n; ++i)
{
scanf("%s", s2[i]);
Insert_Trie(s2[i], i);
}
Build_ac_automaton_fail();
memset(virus, 0, sizeof(virus));
scanf("%s", s1);
Query_ac_automaton(s1);
for (i = 1; i <= n; ++i)
{
if(virus[i])
printf("%s: %d\n",s2[i], virus[i]);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: