标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3065
题意:有n个模式串,一个主串,求每个模式串在主串中出现的次数
思路:AC自动机水题,trie树中也要维护标号,再开一个num数组记录出现次数即可,扫描匹配时注意跳转fail指针和root节点。
code:
1 #include <cstdio> 2 #include <cstring> 3 #include <string> 4 #include <queue> 5 using namespace std; 6 const int KIND = 26; 7 struct node 8 { 9 int id; 10 node* fail; 11 node* next[KIND]; 12 node () 13 { 14 id = 0; 15 fail = NULL; 16 for (int i = 0; i < KIND; ++i) next[i] = NULL; 17 } 18 }; 19 node* root; 20 int L; 21 char str[1005][55]; 22 char text[2000005]; 23 int num[1005]; 24 25 void Insert(char str[]) 26 { 27 node* temp = root; 28 int len = strlen(str); 29 for (int i = 0; i < len; ++i) 30 { 31 int curr = str[i] - ‘A‘; 32 if (temp->next[curr] == NULL) 33 temp->next[curr] = new node(); 34 temp = temp->next[curr]; 35 } 36 temp->id = ++L; 37 } 38 39 void Build() 40 { 41 queue<node*> Q; 42 root->fail = root; 43 for (int i = 0; i < KIND; ++i) 44 { 45 if (root->next[i] == NULL) 46 root->next[i] = root->fail->next[i]; 47 else 48 { 49 root->next[i]->fail = root; 50 Q.push(root->next[i]); 51 } 52 } 53 while (!Q.empty()) 54 { 55 node* temp = Q.front(); 56 Q.pop(); 57 for (int i = 0; i < KIND; ++i) 58 { 59 if (temp->next[i] == NULL) 60 temp->next[i] = temp->fail->next[i]; 61 else 62 { 63 temp->next[i]->fail = temp->fail->next[i]; 64 Q.push(temp->next[i]); 65 } 66 } 67 } 68 } 69 70 void Query() 71 { 72 node* temp = root; 73 int len = strlen(text); 74 for (int i = 0; i < len; ++i) 75 { 76 if (text[i] < ‘A‘ || text[i] > ‘Z‘) 77 { 78 temp = root; 79 continue; 80 } 81 int curr = text[i] - ‘A‘; 82 while (temp->next[curr] == NULL && temp != root) temp = temp->fail; 83 temp = temp->next[curr]; 84 if (temp == NULL) temp = root; 85 node* x = temp; 86 while (x != root) 87 { 88 if (x->id != 0) ++num[x->id]; 89 x = x->fail; 90 } 91 } 92 } 93 94 int main() 95 { 96 int n; 97 while (scanf("%d", &n) != EOF) 98 { 99 L = 0; 100 root = new node(); 101 for (int i = 1; i <= n; ++i) 102 { 103 scanf("%s", str[i]); 104 Insert(str[i]); 105 } 106 Build(); 107 scanf("%s", text); 108 memset(num, 0, sizeof(num)); 109 Query(); 110 for (int i = 1; i <= n; ++i) 111 { 112 if (num[i] == 0) continue; 113 printf("%s: %d\n", str[i], num[i]); 114 } 115 } 116 return 0; 117 }
标签:
原文地址:http://www.cnblogs.com/ykzou/p/4584928.html