http://acm.hdu.edu.cn/showproblem.php?pid=3065
题意:中文题意。
思路:直接插入然后用一个数组记录id和cnt,因为n只有1000,可以开一个数组判断第几个字符串出现过的次数,然后输出就好了。
坑点:多组输入!!!然后因为new出来的空间要自己释放,因此需要用一个vector装起来(似乎多此一举),最后delete掉。
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <queue> 6 using namespace std; 7 #define N 1010 8 #define M 2000010 9 #define TOL 128 10 typedef struct Node { 11 Node* next[TOL]; 12 Node* fail; 13 int id, cnt; 14 Node () { 15 for(int i = 0; i < TOL; i++) next[i] = NULL; 16 id = cnt = 0; 17 fail = NULL; 18 } 19 } node; 20 21 char s[N][55], str[M]; 22 23 class AC_DFA { 24 25 private: 26 node* root; 27 int ans[N], n; 28 vector<node*> dic; 29 30 public: 31 AC_DFA(int now) { 32 dic.clear(); 33 root = new Node(); 34 dic.push_back(root); 35 n = now; 36 memset(ans, 0, sizeof(ans)); 37 } 38 39 ~AC_DFA() { 40 for(int i = 0; i < dic.size(); i++) delete dic[i]; 41 } 42 43 void insert(char *s, int id) { 44 int len = strlen(s); 45 node* now = root; 46 for(int i = 0; i < len; i++) { 47 char c = s[i]; 48 if(now->next[c] == NULL) now->next[c] = new Node(), dic.push_back(now->next[c]); 49 now = now->next[c]; 50 } 51 now->id = id; 52 now->cnt++; 53 } 54 55 void build() { 56 queue<node *> que; 57 que.push(root); 58 root->fail = NULL; 59 while(!que.empty()) { 60 node* now = que.front(); 61 que.pop(); 62 for(int i = 0; i < TOL; i++) { 63 if(now->next[i]) { 64 node* p = now->fail; 65 while(p && p->next[i] == NULL) p = p->fail; 66 if(p) now->next[i]->fail = p->next[i]; 67 else now->next[i]->fail = root; 68 que.push(now->next[i]); 69 } else { 70 if(now == root) now->next[i] = root; 71 else now->next[i] = now->fail->next[i]; 72 } 73 } 74 } 75 } 76 77 void match(char *s) { 78 int len = strlen(s); 79 node *now = root, *p; 80 for(int i = 0; i < len; i++) { 81 char c = s[i]; 82 while(now != root && now->next[c] == NULL) 83 now = now->fail; 84 now = now->next[c]; 85 p = now; 86 while(p) { 87 if(p->cnt) ans[p->id] += p->cnt; 88 p = p->fail; 89 } 90 } 91 } 92 93 void print() { 94 for(int i = 1; i <= n; i++) 95 if(ans[i]) printf("%s: %d ", s[i], ans[i]); 96 } 97 98 }; 99 100 int main() { 101 int n; 102 while(~scanf("%d", &n)) { 103 AC_DFA ac(n); 104 for(int i = 1; i <= n; i++) { 105 scanf("%s", s[i]); 106 ac.insert(s[i], i); 107 } 108 scanf("%s", str); 109 ac.build(); 110 ac.match(str); 111 ac.print(); 112 } 113 return 0; 114 }