http://acm.hdu.edu.cn/showproblem.php?pid=2222
T个测试数据,n个关键字,问所给字符串出现了哪几种关键字。
HDU的测试数据比较弱,提供一组数据
1
2
sher
he
sher
输出 2.
ac代码。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
const int kAho_Corasick_Size_ = 5e5 + 8;
const int kLen_ = 1e6 + 8;
class Aho_Corasick_ {
public:
class Node_ {
public:
int next[26];
int fail, sum;
} tree[kAho_Corasick_Size_];
bool use[kAho_Corasick_Size_];
int size;
//----------------------分界线
void fSet_() {//初始化
memset ( tree, 0, sizeof tree );
size = 1;
}
void fInsert_ ( char *s ) {//字符串插入字典树
int now = 0;
for ( int i = 0; s[i]; i++ ) {
char c = s[i];
if ( !tree[now].next[c - 97] )
tree[now].next[c - 97] = size++;
now = tree[now].next[c - 97];
}
tree[now].sum++;
}
void fBuild_Fail_() { //构造失配指针
std::queue<int>que;
que.push ( 0 );
tree[0].fail = -1;
while ( !que.empty() ) {
int temp = que.front();
que.pop();
for ( int i = 0; i < 26; i++ )
if ( tree[temp].next[i] ) {
if ( temp == 0 ) tree[tree[temp].next[i]].fail = 0;
else {
int p = tree[temp].fail;
while ( p != -1 ) {
if ( tree[p].next[i] ) {
tree[tree[temp].next[i]].fail = tree[p].next[i];
break;
}
p = tree[p].fail;
}
if ( p == -1 )
tree[tree[temp].next[i]].fail = 0;
}
que.push ( tree[temp].next[i] );
}
}
}
int fCatch_ ( int p ) {
int ans = 0;
while ( !use[p] ) {
use[p] = true;
ans += tree[p].sum;
p = tree[p].fail;
}
return ans;
}
int fMatch_ ( char *s ) {
int now = 0, ans = 0;
memset ( use, false, sizeof use );
use[0] = true;
for ( int i = 0; s[i]; i++ ) {
char c = s[i];
if ( tree[now].next[c - 97] )
now = tree[now].next[c - 97];
else {
int p = tree[now].fail;
while ( p != -1 && tree[p].next[c - 97] == 0 ) p = tree[p].fail;
if ( p == -1 ) now = 0;
else now = tree[p].next[c - 97];
}
if ( tree[now].sum || tree[now].fail )
ans += fCatch_ ( now );
}
return ans;
}
};
Aho_Corasick_ Aho;
char temp[kLen_];
int main() {
int T, n;
cin >> T;
while ( T-- ) {
cin >> n;
Aho.fSet_();
while ( n-- ) {
scanf ( "%s", temp );
Aho.fInsert_ ( temp );
}
Aho.fBuild_Fail_();
scanf ( "%s", temp );
cout << Aho.fMatch_ ( temp ) << endl;
}
return 0;
}