首页 > 代码库 > HDU 2222 Keywords Search AC自动机
HDU 2222 Keywords Search AC自动机
题意:给你n个模式串,问一共有多少个模式串在文本串中出现过
解题思路:对于多模式,单文本串的题目显然是要用 AC自动机来解决的,多文本串,单模式串,显然是要用KMP求解的,这也是KMP 和 AC自动机同为字符串匹配的不同之处。
解题代码:
1 // File Name: temp.cpp 2 // Author: darkdream 3 // Created Time: 2014年09月11日 星期四 15时18分26秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #include<queue> 25 #define LL long long 26 #define maxn 500010 27 using namespace std; 28 struct Trie 29 { 30 int next[maxn][26],fail[maxn],end[maxn]; 31 int root, L; 32 int newnode() 33 { 34 for(int i = 0 ;i < 26;i ++) 35 next[L][i] = -1; 36 end[L++] = 0 ; 37 return L-1; 38 } 39 int init() 40 { 41 int L = 0 ; 42 root = newnode(); 43 } 44 int insert(char buf[]) 45 { 46 int len = strlen(buf); 47 int now = root; 48 for(int i = 0 ;i < len ;i ++) 49 { 50 if(next[now][buf[i] - ‘a‘] == -1) 51 { 52 next[now][buf[i] - ‘a‘] = newnode(); 53 } 54 now = next[now][buf[i]-‘a‘]; 55 } 56 end[now]++; 57 } 58 void build() 59 { 60 queue<int> Q; 61 //这里为何要用优先队列来解决这个问题,主要原因是fail指针是按层数来的。 62 fail[root] = root; 63 for(int i = 0;i < 26;i ++) 64 { 65 if(next[root][i] == -1) 66 { 67 next[root][i] = root; //指向root 是没有问题的,我们主要是通过end 数组对个数进行计数的。 68 }else{ 69 fail[next[root][i]] = root; 70 Q.push(next[root][i]); 71 } 72 } 73 while(!Q.empty()) 74 { 75 int now = Q.front(); 76 Q.pop(); 77 for(int i = 0 ;i < 26;i ++) 78 { 79 if(next[now][i] == -1) 80 next[now][i] = next[fail[now]][i]; 81 else{ 82 fail[next[now][i]] = next[fail[now]][i]; 83 Q.push(next[now][i]); 84 } 85 } 86 } 87 } 88 int query(char buf[]) 89 { 90 int len = strlen(buf); 91 int now = root ; 92 int res = 0 ; 93 for(int i = 0 ;i < len;i ++) 94 { 95 now = next[now][buf[i] -‘a‘]; 96 int temp = now ; 97 while(temp != root) 98 { 99 res += end[temp];100 end[temp] = 0 ; 101 temp = fail[temp];// 不断的寻找 fail 指针 因为会出线这样的字符串 abcd bcd cd102 }103 }104 return res;105 }106 };107 char buf[1000010];108 Trie ac;109 int main(){110 int T;111 int n;112 scanf("%d",&T);113 {114 while(T--)115 {116 scanf("%d",&n);117 ac.init();118 for(int i = 0 ;i < n;i ++)119 {120 scanf("%s",buf);121 ac.insert(buf);122 }123 ac.build();124 scanf("%s",buf);125 printf("%d\n",ac.query(buf));126 }127 }128 return 0;129 }
HDU 2222 Keywords Search AC自动机
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。