单词检索(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小游戏
“谁想出来的这么缺德的题目啊!!!!”一个声音在我心中回荡 这个题目很早就在课堂上公布了,我和我的小伙伴都惊呆了! 这是个毛?根本无从下手的感觉 总是觉得这个小游戏不是程序能给出答案的,因为我的第一印 ...
随机推荐
- 【实战】Hadoop安装01-伪分布式-Pseudo
Hadoop安装-伪分布式-Pseudo 〇.所需资料 一.前置环境安装 1.包含内容 (1)安装 虚拟机安装.系统安装 (2)配置 ip.host.主机名配置 关闭防火墙及selinux SSH免密 ...
- 【SQL】SQL常见窗口函数整理汇总大全(用到over的场景)
〇.概述 1.常用网站 SQL窗口函数:https://blog.csdn.net/liangmengbk/article/details/124253806 2.介绍 像聚合函数一样对一组数据进行分 ...
- 【每日一题】【奇偶分别中心扩展/动态规划】2022年2月5日-NC最长回文子串的长度
描述对于长度为n的一个字符串A(仅包含数字,大小写英文字母),请设计一个高效算法,计算其中最长回文子串的长度. 方法1:奇数偶数分别从中心扩展 import java.util.*; public c ...
- 【企业流行新数仓】Day02:DWS层(按日分区的宽表)、DWT层(全量累计表)、ADS层、总结
一.DWS层 1.概括 dwd层的数据,每日轻度聚合,建宽表 表名 粒度 dws_uv_detail_daycount 一个设备是一行 dws_user_action_daycount(只统计今天登录 ...
- Kubernetes-基于容器云构建devops平台
1.基于kubernetes devops的整体方案 本文以Kubernetes为基础,为基于java语言研发团队提供一套完整的devops解决方案.在此方案中,开发人员基于eclipse集成开发环境 ...
- 0停机迁移Nacos?Java字节码技术来帮忙
摘要:本文介绍如何将Spring Cloud应用从开源Consul无缝迁移至华为云Nacos. 本文分享自华为云社区<0停机迁移Nacos?Java字节码技术来帮忙>,作者:华为云PaaS ...
- 什么是django中间件?(七个中间件-自定义中间件)
目录 一:django中间件 1.什么是django中间件 2.django请求生命周期流程图 二:django自带七个中间件 1.研究django中间件代码规律 2.django支持程序员自定义中间 ...
- Jmeter 之跨线程传参
其他线程使用某个线程中提取的值,比如场景:客户端一直与服务端保持连接的同时进行其他业务操作 1.建立以下两个线程组,并添加相应业务接口 2.发送心跳时,需要token,在用户登录接口下添加提取器提取t ...
- uniapp(vue)实现点击左侧菜单,右侧显示对应的内容
<template> <view class="container"> <view class="fication-search" ...
- [机器学习] PCA (主成分分析)详解
转载于https://my.oschina.net/gujianhan/blog/225241 一.简介 PCA(Principal Components Analysis)即主成分分析,是图像处理中 ...