您的位置:首页 > 其它

HDOJ 2222.Keywords Search(AC自动机模板)

2015-08-20 11:16 441 查看
2015-8-20

问题简述:

输入 n 个模式串和一个目标串,问有多少模式串能与目标串匹配。

解题思路:

直接套用AC自动机模板即可。

通过以下链接学习AC自动机:http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html

源代码:

/*
OJ: HDOJ
ID: forever
TASK: 2222.Keywords Search
LANG: C++
NOTE: AC自动机
*/
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#define MAX 1000005
using namespace std;

typedef struct node {
node *next[26];
node *fail;
int cnt;
node() {
fail = NULL;
cnt = 0;
memset( next, NULL, sizeof(next) );
}
}ACTrie;
ACTrie *root = new node;

void build( char * str ) {
int len = strlen(str);
ACTrie *p = root, *q;
for( int i = 0; i < len; i ++ ) {
int id = str[i] - 'a';
if( p -> next[id] == NULL ) {
q = new node;
p -> next[id] = q;
}
p = p -> next[id];
}
p -> cnt ++;
}

void getfail() {
int i;
node *p = root, *son, *temp;
queue<struct node *> que;
que.push(p);
while( !que.empty() ) {
temp = que.front();
que.pop();
for( i = 0; i < 26; i ++ ) {
son = temp -> next[i];
if(son!=NULL) {
if(temp==root)
son -> fail = root;
else {
p = temp -> fail;
while(p) {
if( p -> next[i] ) {
son -> fail = p -> next[i];
break;
}
p = p -> fail;
}
if( !p )
son -> fail = root;
}
que.push(son);
}
}
}
}

void query(char * str) {
int len, i, cnt = 0;
len = strlen(str);
node *p, *temp;
p = root;
for( 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;//
temp = p;

while( temp != root ) {
if( temp -> cnt >= 0 ) {
cnt += temp -> cnt;
temp->cnt=-1;
}
else break;
temp = temp -> fail;
}
}
printf( "%d\n", cnt );
}

int main()
{
int t, n;
scanf( "%d", &t );
char str[MAX];
while( t -- ) {
root = new node;
scanf( "%d", &n );
while( n -- ) {
scanf( "%s", str );
build( str );
}

getfail();
scanf( "%s", str );
query( str );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: