单词检索(search)
单词检索(search)
\(Description\)
小可可是学校图书馆的管理员,现在他接手了一个十分棘手的任务。
由于学校需要一些材料,校长需要在文章中检索一些信息。校长一共给了小可可N篇文章,每篇文章为一个字符串。现在,校长需要他找到这样的单词,它至少在这N篇文章中的M篇文章里出现过,且单词长度为L。可是,工作量十分庞大,但校长又急需小可可完成这项任务。
现在他向你求助,需要你编写程序完成这项艰巨的任务。
\(Input\)
第1行3个正整数N,M,L,表示文章的数目,单词至少出现在M篇文章中和每个单词的长度。
接下来N行,每行一个字符串,表示一篇文章。
\(Output\)
仅一行,表示满足检索条件的单词数。
\(Sample Input\)
3 2 2
noip
istudycpp
imacppstudent
\(Sample Output\)
5
【样例解释】
这5个单词分别为:st,tu,ud,pp,cp。
\(Data Constraint\)
对于20%的数据有1≤N,M≤10;
对于60%的数据有1≤N,M≤100;
对于100%的数据有1≤N,M≤2000,L≤1000。每篇文章长度不大于1000,均有小写字母组成。
思路
字符串?
既然限定了答案字符的长度,那很容易想到分离字符串,统计出现个数
那就是 \(O(nl)\) 级别的个数,空间可以承受
然后怎么存分离出的字符
如果可以
对于每一篇文章,我们把分离的字符去重(因为答案要求的字符至少在N篇文章中的M篇文章里出现过)
最后合在一起
此时统计出现次数超过 \(M\) 的字符数量就是答案
想想,没有问题
关键是分离
如果把每个字符截取下来,那么一片文章处理的复杂度就是 \(O(|S|l)\)
\(n\) 篇就是 \(O(n|S|l)\) 的,显然不可以承受
然后呢?
正解
既然有了思路,那就直接打吧(也有 \(60\) 分了)
可是,现在是追求正解的时候
思路中的瓶颈在于分离字符
而我们知道要获取一段区间的信息,如果满足可加性,那就可以前缀和维护
字符串?
哦,哈希!
具体方式
对于一个字符串,我们对其进行哈希时,考虑映射成一个数字
一个很巧妙的方法是:把字符本身当做一串数字,一个字符对应权值
从高到低每一位的位权就参考十进制的方法,记作 \(B^{k-1}\)
其中 \(k\) 为第 \(k\) 位,\(B\) 是几进制
因为题中字符串均由小写字母构成
所以设为 \(26\) 进制(不这样也行,哈希映射的方法自己选择)
那么对于一个字符串S,有:
\]
截取 S 中后 \(l\) 个字符组成的字符串设为 C',前 \(|S| - l\) 个字符组成的字符串设为 C
则
\]
于是维护 \(s_i =\sum_{k=1}^i H(|1...k|)\)
双模数,以防万一
代码
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
const LL p1 = 1e9 + 7 , p2 = 1e9 + 9 , B = 26;
LL s1[1005] , s2[1005] , b1[1005] , b2[1005];
struct node{
LL x , y;
}d[2000005] , c[2000005];
int cnt , tot , n , m , l , ans;
char ch;
inline bool cmp(node a , node b){return (a.x < b.x || (a.x == b.x && a.y < b.y));}
int main()
{
scanf("%d%d%d" , &n , &m , &l);
b1[0] = b2[0] = 1;
for(register int i = 1; i <= 1001; i++) b1[i] = b1[i - 1] * B % p1;
for(register int i = 1; i <= 1001; i++) b2[i] = b2[i - 1] * B % p2;
int x;
for(register int i = 1; i <= n; i++)
{
x = 0 , s1[0] = 0 , s2[0] = 0 , cnt = 0;
ch = getchar();
while (ch < 'a' || ch > 'z') ch = getchar();
for(; ch >= 'a' && ch <= 'z'; ch = getchar())
{
x++;
s1[x] = (s1[x - 1] * B % p1 + (ch - 'a' + 1)) % p1;
s2[x] = (s2[x - 1] * B % p2 + (ch - 'a' + 1)) % p2;
if (x >= l)
{
d[++cnt].x = (s1[x] + p1 - s1[x - l] * b1[l] % p1) % p1;
d[cnt].y = (s2[x] + p2 - s2[x - l] * b2[l] % p2) % p2;
}
}
sort(d + 1 , d + cnt + 1 , cmp);
c[++tot] = d[1];
for(register int j = 2; j <= cnt; j++)
if (d[j].x != d[j - 1].x || d[j].y != d[j - 1].y)
c[++tot] = d[j];
}
sort(c + 1 , c + tot + 1 , cmp);
x = 1;
while (x <= tot)
{
int s = 1;
while (c[x].x == c[x + 1].x && c[x].y == c[x + 1].y && x < tot) x++ , s++;
if (s >= m) ans++;
x++;
}
printf("%d" , ans);
}
单词检索(search)的更多相关文章
- 英语单词小程序插件 - EdictPlugin-LTS
1.插件引入 全局app.json配置 "plugins": { "edict-plugin": { "version": "1. ...
- 通过trie树实现单词自动补全
/** * 实现单词补全功能 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #incl ...
- 从Search Sort到Join
发表于<程序员>2015年4月B的一篇文章,在博客归档下.根据杂志社要求,在自己博客发表该文章亦须注明:本文为CSDN编译整理,未经允许不得转载,如需转载请联系market#csdn.ne ...
- 告别炼丹,Google Brain提出强化学习助力Neural Architecture Search | ICLR2017
论文为Google Brain在16年推出的使用强化学习的Neural Architecture Search方法,该方法能够针对数据集搜索构建特定的网络,但需要800卡训练一个月时间.虽然论文的思路 ...
- 海量数据处理之Tire树(字典树)
参考博文:http://blog.csdn.net/v_july_v/article/details/6897097 第一部分.Trie树 1.1.什么是Trie树 Trie树,即字典树,又称单词查找 ...
- 搜索系统核心技术概述【1.5w字长文】
前排提示:本文为综述性文章,梳理搜索相关技术,如寻求前沿应用可简读或略过 搜索引擎介绍 搜索引擎(Search Engine),狭义来讲是基于软件技术开发的互联网数据查询系统,用户通过搜索引擎查询所需 ...
- 关于 微软必应词典客户端(pc) 的案例分析
第一部分 调研,评测 ●评测 bug one 在词典界面中搜完单词后,将鼠标移到英文例句上的单词时,会显示对应的中文翻译,而当移到短语时则不对应中文翻译. bug two 用orc强力取词,查询如上图 ...
- ***PHP preg_match正则表达式的使用
第一,让我们看看两个特别的字符:‘^’和‘$’他们是分别用来匹配字符串的开始和结束,以下分别举例说明 : "^The": 匹配以 "The"开头的字符串; &q ...
- Trie树也称字典树
Trie树 Trie树也称字典树,因为其效率很高,所以在在字符串查找.前缀匹配等中应用很广泛,其高效率是以空间为代价的. 一.Trie树的原理 利用串构建一个字典树,这个字典树保存了串的公共前缀信息, ...
- 第四次作业——WORDSEARCH小游戏
“谁想出来的这么缺德的题目啊!!!!”一个声音在我心中回荡 这个题目很早就在课堂上公布了,我和我的小伙伴都惊呆了! 这是个毛?根本无从下手的感觉 总是觉得这个小游戏不是程序能给出答案的,因为我的第一印 ...
随机推荐
- SQL语句查询关键字前期数据准备
前期数据准备 create table emp( id int primary key auto_increment, name varchar(20) not null, gender enum(' ...
- Apache手动安装教程及报错解决梳理
操作参考教程:https://www.cnblogs.com/haw2106/p/9839655.html 下载地址(例):wget https://dlcdn.apache.org/httpd/ht ...
- MyBatis03:连接池及事务控制、xml动态SQL语句、多表操作
今日内容: mybatis中的连接池.事务控制[原理了解,应用会用] mybatis中连接池的使用及分析 mybatis中事务控制的分析 mybatis中基于xml配置的动态SQL语句使用[会用即可] ...
- 【中间件】Docker
一.Docker (一)基础概念 1.概念 是linux容器的一种封装,它是最流行的Linux容器解决方案,由go语言开发 提供简单易用的容器使用接口,方便创建.使用和销毁 2.应用场景 自动打包.持 ...
- python读入中文文本编码错误
python读入中文文本编码错误 python读入中文txt文本: #coding:utf-8 def readFile(): fp = open('emotion_dict//neg//neg_al ...
- 2022-6.824-Lab1:Map&Reduce
lab 地址 : https://pdos.csail.mit.edu/6.824/labs/lab-mr.html 1. 介绍 准备工作 阅读 MapReduce 做什么 实现一个分布式的 Map ...
- [编程基础] C++多线程入门6-事件处理的需求
原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 6 事件处 ...
- App几个可能造成内存泄漏的情况:
App几个可能造成内存泄漏的情况: 1.block块中直接用self调用,self将会被block copy到内部增加一次饮用计数,形成循环引用 在block里调用self会不会造成循环引用和这个bl ...
- 02-RTL代码分析思路
RTL代码分析思路(这里不进行具体代码的分析) verilog文件是以.v结尾的 1 RTL代码示例 //Date : 2023-01-09 //E-mail : xxxxxx@163.com //c ...
- Unity - 创建C#脚本默认编码格式为UTF8
嗨咯大家好,哈哈哈哈哈哈哈哈哈哈,今儿小黑加班,目的只有一个,解决Unity创建的脚本通过VS打开后编码格式不正确,导致从Unity的Inspector面板与Mac上边的VS看到的中文为乱码,很气,找 ...