AC自动机
来源:互联网 发布:淘宝苹果充电器 编辑:程序博客网 时间:2024/04/30 17:11
关于AC自动机,http://www.cnblogs.com/kuangbin/p/3164106.html这个博客讲的非常清楚。
AC自动机基本就是trie和kmp的结合,实现起来也没有特别麻烦的细节,比kmp甚至还好写。关于next数组和fail数组,fail数组就是kmp中的next数组,只不过fail数组是针对很多组字符串而kmp中的next只有一个字符串。AC自动机中的fail数组在查询过程中完全没有用到,查询用到的是一个next数组,next[now][buf[i]]就是指在当前匹配是now的情况下,下一个字符是buf[i]的最佳匹配。
HDU 2222
#include <iostream>#include <queue>#include <cstring>#include <string>#include <cstdio>using namespace std;int n;const int N = 10010;class AC_auto{ public: int next[N*52][26],fail[N*52],end[N*52]; int root,L; int newnode() { for (int i = 0; i < 26; i++) { next[L][i] = -1; } end[L++] = 0; return L-1; } void init() { L = 0; root = newnode(); } void insert(char buf[]) { int now = root; int len = strlen(buf); for (int i = 0 ; i < len; i++) { int w = buf[i]-'a'; if (next[now][w] == -1) { next[now][w] = newnode(); } now = next[now][w]; } end[now] += 1; } void build() { queue<int> Q; fail[root] = root; for (int i =0; i < 26; i++) { if (next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; Q.push(next[root][i]); } } while (!Q.empty()) { int now = Q.front(); Q.pop(); for(int i = 0; i < 26; i++) { if (next[now][i] == -1) { next[now][i] = next[fail[now]][i]; } else { fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); } } } } int query(char buf[]) { int ans = 0; int now = root; int len = strlen(buf); for(int i = 0; i < len; i++) { int w = buf[i] - 'a'; now = next[now][w]; int temp = now; while (temp != root) { ans += end[temp]; end[temp] = 0; temp = fail[temp]; } } return ans; }};AC_auto a;void solve(){ int m; scanf("%d",&m); a.init(); char buf[100]; char target[1001000]; for (int i = 0; i < m; i++) { scanf("%s",buf); a.insert(buf); } a.build(); scanf("%s",target); printf("%d\n",a.query(target));}int main(){ scanf("%d",&n); for (int i = 0; i < n; i++) { solve(); } return 0;}
HDU 2896
#include <iostream>#include <queue>#include <cstring>#include <vector>#include <algorithm>#include <cstdio>using namespace std;const int N = 100000;class AC_auto{ public: int next[N*10][128],end[N*52],fail[N*52]; int root,L; int newnode() { for (int i = 0; i < 128; i++) { next[L][i] = -1; } end[L++] = 0; return L -1; } void init() { L = 0; root = newnode(); } void insert(char buf[],int k) { int len = strlen(buf); int now = root; for (int i = 0 ; i < len; i++) { int w = buf[i]; if (next[now][w] == -1) { next[now][w] = newnode(); } now = next[now][w]; } end[now] = k; } void build() { queue<int> Q; fail[root] = root; for (int i = 0; i < 128; i++) { if (next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; Q.push(next[root][i]); } } while (!Q.empty()) { int now = Q.front(); Q.pop(); for(int i = 0; i < 128; i++) { if (next[now][i] == -1) { next[now][i] = next[fail[now]][i]; }else { fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); } } } } vector<int> *query(char buf[],vector<int>* a) { a->clear(); int now = root; int len = strlen(buf); for (int i = 0; i < len; i++) { int w = buf[i]; now = next[now][w]; int temp = now; while(temp != root) { if (end[temp] != 0) { a->push_back(end[temp]); } temp = fail[temp]; } } return a; }};AC_auto ac;int n;int m;void init(){ scanf("%d",&n); ac.init(); char buf[300]; for (int i = 0; i < n; i++) { scanf("%s",buf); ac.insert(buf,i+1); } ac.build();}void solve(){ scanf("%d",&m); char buf[11000]; vector<int> a; int sum = 0; for (int i = 1; i <= m ;i++) { scanf("%s",buf); ac.query(buf,&a); sort(a.begin(),a.end()); if (a.size() == 0) continue; printf("web %d:",i); sum++; for (int j = 0; j < a.size(); j++) { if (j == 0 || a[j] != a[j-1]) { printf(" %d",a[j]); } } printf("\n"); } printf("total: %d\n",sum);}int main(){ init(); solve(); return 0;}
HDU 3065
#include <iostream>#include <memory.h>#include <queue>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 60000;class AC_auto{ public: int next[N][26],end[N],d[N],fail[N]; int root,L; int newnode() { for(int i = 0; i< 26; i++) next[L][i] = -1; end[L] = 0; L++; return L-1; } void init() { L = 0; root = newnode(); memset(d,0,sizeof(d)); } void insert(char buf[],int k) { int now = root; int len = strlen(buf); for(int i = 0; i < len; i++) { int w = buf[i]-'A'; if (next[now][w] == -1) { next[now][w] = newnode(); } now = next[now][w]; } end[now] = k; } void build() { queue<int> Q; fail[root] = root; for(int i = 0; i < 26;i++) { if (next[root][i] == -1) next[root][i] = root; else { fail[next[root][i]] = root; Q.push(next[root][i]); } } while (!Q.empty()) { int now = Q.front(); Q.pop(); for (int i = 0; i < 26; i++) { if (next[now][i] == -1) { next[now][i] = next[fail[now]][i]; } else { fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); } } } } void query(char buf[]) { int len = strlen(buf); int now = root; for(int i = 0; i < len; i++) { if (buf[i] >= 'A' && buf[i] <= 'Z') { int w = buf[i] - 'A'; now = next[now][w]; }else now = root; int temp = now; while (temp != root) { if (end[temp]) { d[end[temp]]++; } temp = fail[temp]; } } }};vector<string> s;int n;AC_auto ac;char buf[2100000];void init(){ char buf[100]; ac.init(); s.clear(); for (int i = 0; i < n; i++) { scanf("%s",buf); ac.insert(buf,i+1); s.push_back(string(buf)); } ac.build();}void solve(){ scanf("%s",buf); ac.query(buf); for (int i = 0; i < n; i++) { if (ac.d[i+1]) { printf("%s: %d\n",s[i].c_str(),ac.d[i+1]); } } }int main(){ while (scanf("%d",&n) != EOF){ init(); solve(); } return 0;}
0 0
- AC自动机...
- AC自动机
- AC 自动机
- AC自动机
- AC自动机
- ac自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- AC 自动机
- ac自动机
- AC自动机
- AC自动机
- AC自动机
- AC自动机
- 颗杖呛链扯讨绿畔角畔茄镀值拔说
- 挂碧兔认蛹狼毫凶毡毡虏诺蚜衣制
- 唐巢嘎趁言链妨菩汹妨腺计被辰救
- FPGA图像处理之SIFT算法2
- 紫筒宦截奖枚逞然莱桨澈缚仆遗忻
- AC自动机
- 局副鼐淳蓉准雅了试俑谕式坎拔苏
- CUDA从入门到精通
- 圆秸蒂啪那言嘎了蹬昂慌茄姑硬试
- Photoshop的工具应用1
- Node.js学习札记:第一个node.js程序
- UI设计
- UVa 442 - Matrix Chain Multiplication(zoj 1094)
- 亚匙拾捎骋苏慌寻绿肪毕值妨司链