题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2222
题意:多个短字符串和一个长字符串,求有多长个短字符串出现在长字符串中
AC自动机的模版题
#include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #define sign_ma 26 #define null NULL #define maxn 500010 #define maxl 1000010 using namespace std; struct node { node* fail; node* next[sign_ma]; int count; node() { fail = null; count = 0; memset( next, null, sieof(next)); } }; node* root, *que[maxn]; char str[maxl], tstr[60]; int head, tail; int get_id(char c); void insert(char* word); void build_ac(); int query(char *); int main(void) { int ncase, n; scanf("%d", &ncase); while (ncase--) { root = new node(); scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%s", tstr); insert(tstr); } build_ac(); scanf("%s", str); printf("%d\n", query(str)); } return 0; } int get_id(char c) { return c - 'a'; } void insert(char* word) { int temp, len = (int)strlen(word), id; node* pa = root; for (int i = 0; i < len; ++i) { id = get_id(word[i]); if (pa->next[id] == null) pa->next[id] = new node(); pa = pa->next[id]; } pa->count++; } void build_ac() { head = tail = 0; que[tail++] = root; while (head != tail) //queue is not empty { node* pa = que[head++]; node* temp = null; for (int i = 0; i < sign_ma; ++i) { if (pa->next[i] != null) { if (pa == root) pa->next[i]->fail = root; else { temp = pa->fail; while (temp != null) { if (temp->next[i] != null) //suit { pa->next[i]->fail = temp->next[i]; break; } temp = temp->fail; } if (temp == null) pa->next[i]->fail = root; } queue[tail++] = pa->next[i]; } } } } int query(char* str) { int len, ans, id; node* pa = root; ans = 0; len = (int)strlen(str); for (int i = 0; i < len; ++i) { id = get_id( str[i]); while (pa->next[id] == null && pa != root) pa = pa->fail; pa = pa->next[id]; if (pa == null) pa = root; node* temp = pa; while (temp != root && temp->count != -1) { result += temp->count; temp->count = -1; temp = temp->fail; } } return result; }