【字符串·ac自动机】uva1449Dominating Patterns
来源:互联网 发布:java的反射机制详解 编辑:程序博客网 时间:2024/05/18 10:11
ac自动机的基本用途是实现多个模板串在一个文本串中的匹配
如:a acd bbca aca 在 aacdacacabbcac中分别出现了几次?
在trie树上计算一些新的东西;
失配数组f[maxn]: 如果在文本串I点失配,那还能去哪个节点碰碰运气
后缀链接last[maxn]: 节点j沿着失配链接往回走,遇到的下一个单词节点编号;
题目uva4670,找出出现次数最多的字符串,用不同的数表示不同的单词结尾,将print函数改为字符串计数器+1;
模板串可能有重复,后一个字符串的val会覆盖前一个字符串,这时用一个映射,两个字符串可以映射到同一个索引,答案输出两遍;
#define _CRT_SECURE_NO_WARNINGS#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<map>using namespace std;typedef long long ll;const int maxn = 1000010;int ch[maxn][26];int val[maxn];int sz;int idx(char c){ return c - 'a'; }char P[155][75]; //数组要开大一点map<string, int> ms;char str[maxn];void insert(char *s, int v){ int u = 0, n = strlen(s); for (int i = 0; i < n; i++){ int c = idx(s[i]); if (!ch[u][c]){ memset(ch[sz], 0, sizeof(ch[sz])); val[sz] = 0; ch[u][c] = sz++; } u = ch[u][c]; } val[u] = v; ms[string(s)] = v;}int n;int nex[maxn];int last[maxn];int cnt[maxn];void init(){ ms.clear(); sz = 1; memset(ch[0], 0, sizeof(ch[0])); memset(cnt, 0, sizeof(cnt)); for (int i = 1; i <= n; i++){ scanf("%s", P[i]); insert(P[i], i); }}void getNext(){ memset(nex, 0, sizeof(nex)); memset(last, 0, sizeof(last)); queue<int> q; nex[0] = 0; for (int c = 0; c < 26; c++){ int u = ch[0][c]; if (u) { nex[u] = 0; q.push(u); last[u] = 0; } } while (!q.empty()){ int r = q.front(); q.pop(); for (int c = 0; c < 26; c++){ int u = ch[r][c]; if (!u) continue; q.push(u); int v = nex[r]; while (v&&!ch[v][c]) v = nex[v]; nex[u] = ch[v][c]; last[u] = val[nex[u]] ? nex[u] : last[nex[u]]; } }}void print(int j){ if (j){ cnt[val[j]]++; print(last[j]); }}void find(char *t){ int len = strlen(t); int j = 0; for (int i = 0; i < len; i++){ int c = idx(t[i]); while (j&&!ch[j][c]) j = nex[j]; j = ch[j][c]; if (val[j]) print(j); else if (last[j]) print(last[j]); }}int main(){ while (~scanf("%d", &n) && n){ init(); getNext(); scanf("%s", str); find(str); int top = -1; for (int i = 1; i <= n; i++){ if (cnt[i] > top) top = cnt[i]; } printf("%d\n", top); for (int i = 1; i <= n; i++){ if (cnt[ms[string(P[i])]] == top) printf("%s\n", P[i]); } } return 0;}
阅读全文
0 0
- 【字符串·ac自动机】uva1449Dominating Patterns
- LA4670 Dominating Patterns[AC自动机]
- LA 4670 Dominating Patterns (AC自动机)
- LA - 4670 - Dominating Patterns(AC自动机)
- LA 4670 dominating patterns AC自动机
- UVALive 4670 Dominating Patterns(AC自动机)
- LA 4760 Dominating Patterns AC自动机
- UVa:1449 Dominating Patterns(AC自动机)
- UVA 1449 Dominating Patterns(AC自动机)
- UVA 1449 - Dominating Patterns(AC自动机)
- UVALive 4670 - Dominating Patterns (AC自动机)
- LA 4670 Dominating Patterns,AC自动机
- uva 1449 - Dominating Patterns(AC自动机)
- uva 1449 Dominating Patterns(ac自动机)
- 【UVA】1449-Dominating Patterns(AC自动机)
- LA 4670 Dominating Patterns (ac自动机)
- UVaLA 4670 Dominating Patterns AC自动机
- UVAlive 4670 Dominating Patterns [AC自动机]
- c语言初步经典题11--坐标转换
- 小白算法练习 NYOJ 吝啬的国度 dfs+邻接表
- 寻找三角形 (海伦公式)
- 外卖“搭上”高铁已成事实,然叫好叫座难兑现?
- python链家网二手房数据爬取
- 【字符串·ac自动机】uva1449Dominating Patterns
- 机器学习入门-线性回归
- Linux启动/停止/重启XAMPP(禅道)
- 集合
- perl_正则表达式
- mysql(5.6)分区(一)分区键,主键和唯一键
- 网站开发(一)环境配置及模板准备
- mysql 数据引擎
- 完美解决Python2操作中文名文件乱码的问题