AC自动机可以在线性时间内匹配多个模式串,算法思路是一个在trie上使用KMP算法
trie的讲解和AC自动机算法具体讲解(dalao的帖子)
http://www.cppblog.com/menjitianya/archive/2014/07/10/207604.html
//hdu2222
#define clr(a,x) memset(a,x,sizeof a)
struct Aho {
struct state {
int next[26];
int fail, cnt;
}stateTable[maxn];
int size;
queue<int> que;
void init() {
while (que.size()) que.pop();
for (int i = 0; i < maxn; i++) {
clr(stateTable[i].next, 0);
stateTable[i].fail = stateTable[i].cnt = 0;
}
size = 1;
}
void insert(char *s) {
int n = strlen(s);
int now = 0;
for (int i = 0; i < n; i++) {
char c = s[i];
if (!stateTable[now].next[c - 'a'])
stateTable[now].next[c - 'a'] = size++;
now = stateTable[now].next[c - 'a'];
}
stateTable[now].cnt++;
}
void build() {
stateTable[0].fail = -1;
que.push(0);
while (que.size()) {
int u = que.front();
que.pop();
for (int i = 0; i < 26; i++) {
if (stateTable[u].next[i]) {
if (u == 0) stateTable[stateTable[u].next[i]].fail = 0;
else {
int v = stateTable[u].fail;
while (v != -1) {
if (stateTable[v].next[i]) {
stateTable[stateTable[u].next[i]].fail = stateTable[v].next[i];
break;
}
v = stateTable[v].fail;
}
if (v == -1) stateTable[stateTable[u].next[i]].fail = 0;
}
que.push(stateTable[u].next[i]);
}
}
}
}
int Get(int u) {
int res = 0;
while (u) {
res = res + stateTable[u].cnt;
stateTable[u].cnt = 0;
u = stateTable[u].fail;
}
return res;
}
int match(char *s) {
int n = strlen(s);
int res = 0, now = 0;
for (int i = 0; i < n; i++) {
char c = s[i];
if (stateTable[now].next[c - 'a']) {
now = stateTable[now].next[c - 'a'];
}
else {
int p = stateTable[now].fail;
while (p != -1 && stateTable[p].next[c - 'a'] == 0) p = stateTable[p].fail;
if (p == -1) now = 0;
else now = stateTable[p].next[c - 'a'];
}
if (stateTable[now].cnt)
res = res + Get(now);
}
return res;
}
}aho;
int T;
int N;
char S[maxn];
int main() {
scanf("%d", &T);
while (T--) {
aho.init();
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%s", S);
aho.insert(S);
}
aho.build();
scanf("%s", S);
printf("%d\n", aho.match(S));
}
return 0;
}