hdu 2222 Keywords Search(AC自动机)
来源:互联网 发布:旅行翻译官软件 编辑:程序博客网 时间:2024/04/30 17:36
题意:
给你很多个单词,然后给你一篇文章,问给出的单词在文章中出现的次数。
解析:
直接套用AC自动机的模板。
注意:
每个单词在目标串中出现的话,只能记为一次。
#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;const int maxnode = (int)1e6 + 10;const int sigma_size = 26;struct AC { int ch[maxnode][sigma_size]; int fail[maxnode]; int last[maxnode]; int val[maxnode]; int sz; int ans; void clear() { sz = 1; memset(ch[0], 0, sizeof(ch[0])); } inline int idx(char c) { return c - 'a'; } void insert(char *s) { 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]++; } int find(char* tar) { int n = strlen(tar); int v = 0; ans = 0; for(int i = 0; i < n; i++) { int c = idx(tar[i]); while(v && !ch[v][c]) v = fail[v]; v = ch[v][c]; if(val[v]) print(v); else if(last[v]) print(last[v]); } return ans; } void print(int j) { while(j) { ans += val[j]; //找到的话,将所有的val[j]都加进来 val[j] = 0; //然后将val[j]清空,之后就算有相同的单词也可以不用计算。 j = last[j]; } } int getFail() { //构造失配指针 queue<int> que; //初始化队列 //root的子节点的失配指针都指向root。 for(int c = 0; c < sigma_size; c++) { int u = ch[0][c]; if(u) { fail[u] = 0; que.push(u); last[u] = 0; } } //节点(字符为x)的失败指针指向:从x节点的父节点的fail节点回溯直到找到某节点的子节点也是字符x,没有找到就指向root。 //按照bfs顺序计算失配函数 while(!que.empty()) { int r = que.front(); que.pop(); //取出队首,遍历当前的子节点 for(int c = 0; c < sigma_size; c++) { int u = ch[r][c]; //当前的子节点 if(!u) continue; //且子节点不能为空 que.push(u); //将不为空的子节点存入队列 int v = fail[r]; //r = x 节点的父节点的fail节点 //从x节点的父节点的fail节点回溯,直到找到某节点的子节点也是字符x //ch[v][c] == 0表示其子节点不是x,可以继续向上找; //v != 0,fail[v]存在,表示还能向上找 while(v && !ch[v][c]) v = fail[v]; fail[u] = ch[v][c]; //找到某节点的子节点也是字符x,将u的失配指针指向最近的某节点的子节点也是字符x last[u] = val[fail[u]] ? fail[u] : last[fail[u]]; } } }} ac;const int MAXN = (int)1e4 + 10;char key[MAXN][55];char tar[maxnode];int n;int main() { int T; scanf("%d", &T); while(T--) { ac.clear(); scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%s", key[i]); ac.insert(key[i]); } ac.getFail(); scanf("%s", tar); printf("%d\n", ac.find(tar)); } return 0;}
0 0
- hdU 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- HDU 2222 Keywords Search (AC自动机)
- hdu - 2222 - Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC 自动机)
- HDU 2222 - Keywords Search (AC自动机)
- HDU - 2222 Keywords Search (AC自动机)
- HDU - 2222 Keywords Search (AC自动机)
- HDU 2222 Keywords Search(AC自动机)
- HDU 2222 Keywords Search (AC自动机)
- HDU 2222 Keywords Search(AC自动机)
- hdu 2222 Keywords Search(AC自动机)
- HDU 2222 Keywords Search (AC自动机)
- HDU 2222Keywords Search (ac自动机)
- HDU 2222 Keywords Search(AC自动机)
- HDU-2222 Keywords Search(AC自动机)
- 写给大家看的项目管理书(第3版)——互动出版网
- jsp中的四大作用域
- leetcode Pascal's Triangle
- js创建Form表单并提交
- Hibernate的三种状态
- hdu 2222 Keywords Search(AC自动机)
- OpenLayers Labeled Features Example
- [Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段
- Binary Tree Level Order Traversal II
- 可重入函数
- 淘宝如何跨域获取Cookie分析
- SQL语句 where 1=1 && where 1<>1
- 大型网站架构演变和知识体系
- 加盐hash保存密码的正确方式