做的第一道AC自动机专题的题目。。。

题意:给你一堆单词和一个文本串,求出文本串中出现次数最多的单词。

思路:AC自动机。这道题是AC自动机的基本应用。建立一个AC自动机,用val[u]=1表示节点u处为一个单词的尾节点,否则val[u]=0。然后用文本串去匹配,每经过一个val[u]=1的点就把计数数组cnt[i]++;(i为第i个单词),最后找cnt中值最大的,然后再遍历一遍cnt数组,值等于最大值就输出该单词。(因为出现次数最多的可能不止一个单词)

注意:输入的单词可能有重复的情况。如果一个单词输入了两遍,那么第二次输入这个单词时就会覆盖第一次输入的这个单词,导致第一次输入的这个单词对应的cnt最终为0。然而如果这个单词出现次数最多我们是要输出两遍的。因此我们再建立一个map映射,不管一个单词输入了几遍,我们都把它映射到这个单词最后一次输入的位置的编号,然后输出的时候直接找每个单词map对应的位置的编号,只要cnt[该单词的编号]==最大值 就输出。具体见代码。

AC代码:

#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
const int mo=1e9+7;
const int mx=10010;
const int ssize=26;
const int inf=0x3f3f3f3f;
map<string,int> mp;
struct ACzdj{int ch[mx][ssize];int val[mx];int f[mx];int last[mx];int sz;int cnt[200];void init(){memset(ch[0],0,sizeof(ch[0]));sz=1;val[0]=0;mp.clear();memset(cnt,0,sizeof(cnt));}void insert(char *s,int v){int u=0,n=strlen(s);for(int i=0;i<n;i++){int id=s[i]-'a';if(ch[u][id]==0){ch[u][id]=sz;memset(ch[sz],0,sizeof(ch[sz]));val[sz++]=0;}u=ch[u][id];}val[u]=v;mp[string(s)]=v;//直接把该单词映射到一个编号,这样不管输入几遍每个单词都只对应一个编号}void print(int i){if(val[i]){cnt[val[i]]++;print(last[i]);}}void find(char *s){int n=strlen(s),j=0;for(int i=0;i<n;i++){int id=s[i]-'a';while(j&&ch[j][id]==0) j=f[j];j=ch[j][id];if(val[j]) print(j);else if(val[last[j]]) print(last[j]);}}
void getFail()
{queue<int> q;last[0]=f[0]=0;for(int i=0;i<ssize;i++){int u=ch[0][i];if(u){f[u]=last[u]=0;q.push(u);}}while(!q.empty()){int r=q.front();q.pop();for(int i=0;i<ssize;i++){int u=ch[r][i];if(!u) continue;q.push(u);int v=f[r];while(v&&ch[v][i]==0) v=f[v];f[u]=ch[v][i];last[u]=val[f[u]]?f[u]:last[f[u]];}}
}
};
ACzdj ac;
char word[160][80];
char t[1000100];
int main()
{int n;while(scanf("%d",&n)==1&&n){ac.init();for(int i=1;i<=n;i++){scanf("%s",word[i]);ac.insert(word[i],i);}ac.getFail();scanf("%s",t);ac.find(t);int maxnum=-1;for(int i=1;i<=n;i++){if(ac.cnt[i]>maxnum){maxnum=ac.cnt[i];//找出出现次数最多的单词出现的次数}}printf("%d\n",maxnum);for(int i=1;i<=n;i++)if(ac.cnt[mp[string(word[i])]]==maxnum)//通过mp来获得单词唯一对应的编号,这样就不怕重复输入了printf("%s\n",word[i]);}return 0;
}

uva 1449 Dominating Patterns(AC自动机基本应用)相关推荐

  1. AC自动机加强版 uva 1449 - Dominating Patterns

    AC自动机最初作用  一个常见的例子就是给出n个单词,再给出一段包含m个字符的文章,让你找出有多少个单词在文章里出现过. 当然这不是AC自动机的全部作用. 本文就是一例,给出几个单词,查询在text里 ...

  2. LA4670 Dominating Patterns[AC自动机]

    The archaeologists are going to decipher a very mysterious "language". Now, they know many ...

  3. UVA 11468 Substring(AC自动机+dp)

    题意就是给你几个模板串,以及一些字符的出现概率,随机选择字符L次后得到一个长度为L的字符串,问这个字符串不包括任何一个模板串的概率. 比较简单的题,把模板串构建成AC自动机,随机选择字符相当于在字典树 ...

  4. UVa 11468 (AC自动机 概率DP) Substring

    将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. 1 #include < ...

  5. AC自动机——Uva 11468 子串

    题目链接:http://vjudge.net/contest/142513#problem/A 题意:给出一些字符和各自对应的选择概率,随机选择L次后将得到一个长度为L的随机字符串S.给出K个模版串, ...

  6. LA_4670_Dominating_Patterns_(AC自动机+map)

    描述 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  7. CDOJ1633 Video Game Combos [AC自动机+dp]

    题目地址:http://acm.uestc.edu.cn/problem.php?pid=1633 AC自动机+BFS AC自动机,参见:http://www.cnblogs.com/luna-lov ...

  8. KMP算法、AC自动机算法的原理介绍以及Python实现

    KMP算法 要弄懂AC自动机算法,首先弄清楚KMP算法. 这篇文章讲的很好: http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E ...

  9. hihocoder第218周:AC自动机

    题目链接 问题描述 给定n个单词,给定一个长字符串s,单词总长度和字符串s的长度都不超过1e5.要求把s中所有的出现单词的位置用*替代. 例如: 样例输入 2 abc cd abcxyzabcd 样例 ...

  10. 2018北京ICPC H. Approximate Matching(AC自动机+DP)

    H : Approximate Matching 时间限制:1000ms,单点时限:1000ms,内存限制:512MB 描述 String matching, a common problem in ...

最新文章

  1. 基于Service Mesh构建更现代的服务架构
  2. java项目校内网的描述_[导入]校内网的错误信息
  3. We will be discontinuing the Nitrous Development Platform and Cloud IDE on November 14th, 2016.
  4. 【Docker】Segmentation Fault or Critical Error encountered. Dumping core and abort
  5. Host '***' is blocked because of many connection errors...
  6. wamp 局域网访问
  7. 梅林系统软件无法安装解决方法
  8. python语音识别终极指南_Python语音识别终极指南
  9. 关于word与wps可共用的的快捷键
  10. Android音频之多设备同时输出-cast通路分析
  11. 使用PIL和OpenCV在PC上模拟动画OLED / LCD显示器
  12. python算方差_python 求方差python函数每日一讲 - divmod数字处理函数
  13. Android USB电源管理
  14. 学校计算机协会面试自我介绍,个人社团面试自我介绍范文三篇
  15. vue+element 下拉框回显时间少一天
  16. FISCO BCOS最强学习路径,汇聚全网资源(2022更新版)
  17. 【element】progress-修改进度条形状、高度、颜色、动态传值
  18. 游戏分类 PRG AVG
  19. ZBrush菜单栏详解(二),3D建模新手必走的进阶之路
  20. 自然语言处理(NLP)常用开源工具总结----不定期更新

热门文章

  1. 笔记:torch的基本运算
  2. 微信wifi服务器地址,从零开始改造路由器实现微信连WIFI的功能(七):更简单的认证服务器wifidog-server...
  3. WindowsCluster 由于在更新安全DNS区域时访问被拒绝,群集网络资源无法注册一个或多个关联的DNS名称
  4. x5650服务器装系统,笔记本处理器天梯图,小猪教您最新笔记本显卡天梯图
  5. IOS开发-ERROR ITMS-90096: Your binary is not optimized for iPhone 5
  6. 梯形波c语言程序利用tlc5615,TLC5615 10Bit DA正弦波信号发生器仿真原理图及源程序...
  7. STRAIGHT分析合成算法
  8. Spring 事务源码(7)—事务的completeTransactionAfterThrowing回滚、commitTransactionAfterReturning提交以及事务源码总结【一万字】
  9. java文章采集爬虫代码示例
  10. python中tree 100 6_Python neighbors.BallTree方法代碼示例