AC自动机指针版本和数组版本
来源:互联网 发布:java ee基础实用教程 编辑:程序博客网 时间:2024/05/22 03:16
#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;#define N 100003struct Tr{ int cnt; Tr *ne[26]; Tr *fail; Tr() { cnt = 0; for (int i = 0;i < 26;i++) ne[i] = NULL; fail = NULL; } void init() { cnt = 0; for (int i = 0;i < 26;i++) ne[i] = NULL; fail = NULL; }}root, tr[N];int tot;void Insert(char *s) { Tr *p = &root; int endId = 0; while (s[endId]) { int id = s[endId]-'a'; if (p->ne[id] == NULL) { p->ne[id] = &tr[++tot]; tr[tot].init(); } p = p->ne[id]; endId++; } p->cnt++;}int query(char *s) { int i, j, re = 0; Tr *p = &root; for (i = 0;s[i];i++) { int id = s[i]-'a'; while (p->ne[id] == NULL && p != (&root)) p = p->fail; p = p->ne[id]; if (p == NULL) p = &root; Tr *tmp = p; while (tmp != (&root) && tmp->cnt != -1) { re += tmp->cnt; tmp->cnt = -1; tmp = tmp->fail; } } return re;}char s[N], t[N];Tr* Q[N];void build() { Tr *p = &root; root.fail = NULL; int f = 0, r = 1; Q[f] = p; while (f < r) { p = Q[f++]; for (int i = 0;i < 26;i++) { if (p->ne[i]) { if (p == (&root)) p->ne[i]->fail = &root; else { Tr *tmp = p->fail; while (tmp != NULL) { if (tmp->ne[i]) { p->ne[i]->fail = tmp->ne[i]; break; } tmp = tmp->fail; } if (tmp == NULL) p->ne[i]->fail = &root; } Q[r++] = p->ne[i]; } } }}int main() { int T, n, i, j; scanf("%d", &T); while (T--) { tot = 0; root.init(); scanf("%d", &n); getchar(); int mxlen = 0; for (i = 0;i < n;i++) { gets(s); int len = strlen(s); if (mxlen < len) { mxlen = len; strcpy(t, s); } Insert(s); } build(); if (query(t) == n) { puts(t); }else puts("No"); }}
#include<cstdio>#include<cstring>#include<queue>using namespace std;#define N 100003struct Tr{ int tr[N][26], cnt[N], fail[N]; int root, tot; int newTr() { int i, d = ++tot; for (i = 0;i < 26;i++) tr[d][i] = 0; fail[d] = cnt[d] = 0; return d; } void init() { tot = 0; root = newTr(); } void Insert(char *s) { int d = root; for (int i = 0;s[i];i++) { int id = s[i]-'a'; if (tr[d][id] == 0) tr[d][id] = newTr(); d = tr[d][id]; } cnt[d]++; } void build() { queue<int> Q; Q.push(root); while (!Q.empty()) { int d = Q.front(); Q.pop(); for (int i = 0;i < 26;i++) { if (tr[d][i]) { if (d == root) { fail[tr[d][i]] = root; }else { int tmp = fail[d]; while (tmp) { if (tr[tmp][i]) { fail[tr[d][i]] = tr[tmp][i]; break; } tmp = fail[tmp]; } if (tmp == 0) fail[tr[d][i]] = root; } Q.push(tr[d][i]); } } } } int query(char *s) { int d = root, i, re = 0; for (i = 0;s[i];i++) { int id = s[i]-'a'; while (d != root && tr[d][id] == 0) d = fail[d]; d = tr[d][id]; if (d == 0) d = root; int tmp = d; while (tmp != root && cnt[tmp] != -1) { re += cnt[tmp]; cnt[tmp] = -1; tmp = fail[tmp]; } } return re; }}ans;char s[N], t[N];int main() { int T, n, i, j; scanf("%d", &T); while (T--) { ans.init(); scanf("%d", &n); getchar(); int mxlen = 0; for (i = 0;i < n;i++) { gets(s); int len = strlen(s); if (mxlen < len) { mxlen = len; strcpy(t, s); } ans.Insert(s); } ans.build(); if (ans.query(t) == n) { puts(t); }else puts("No"); }}
阅读全文
0 0
- AC自动机指针版本和数组版本
- AC自动机模板(数组+指针)hdu2222
- hdu 2896 AC自动机(指针+数组)
- hdu 3065 AC自动机(指针+数组)
- AC自动机板子(指针,数组)
- AC自动机完整代码——数组实现,非指针
- AC自动机数组写法
- AC自动机和Trie
- [hdu2222] AC自动机 数组版
- hdu 2222 AC自动机模板题(指针版+数组版)
- HUD 2222 AC自动机摸 解法:1.暴力.2.指针型代码.3.数组型代码
- 关于AC自动机fail指针的灵感
- hdu2222 AC自动机入门 指针型模板
- AC自动机的失败指针树
- hdu 2896 ac自动机(last指针)
- (详解)无指针AC自动机
- 模板_KMP和AC自动机
- bzoj3172 AC自动机+标记和
- 四大组件的运行状态
- 【JavaScript】面向对象与原型
- 数据结构基础(3)一些概念
- 一些REST架构设计模式的理解
- FPGA EDA
- AC自动机指针版本和数组版本
- IDEA下java连接Mysql数据库
- web插入音频文件
- Android Studio 安装初次运行,Building gradle project info
- python 字符串替换
- Idea基础操作
- 利用v-model实现父子组件间的双向通信
- 贝叶斯分类
- Python中列表的append、insert、extend区别