堆的应用:如何快速获取到TOP10最热门的搜索关键词?

就是搜索引擎的热门搜索排行榜,搜索引擎每天会接收大量的用户搜索请求,他会把用户输入的搜索关键词记录下来,然后再离线统计分析,得到TOP10搜索关键词

假设我们有一个包含10亿个搜索关键词的日志文件,如何能快速获取到热门榜TOP10搜索关键词?

堆的应用一:优先级队列

优先级队列,首先是一个队列,队列的最大特性就是先进先出,不过,在优先级队列中,数据的出队顺序不是先进先出的,按照优先级来,优先级最高的,最先出队

用堆来实现一个优先级队列,因为堆和优先级队列非常相似,一个堆可以看作是一个优先级队列,往优先级队列中插入一个元素,相当于往堆里插入一个元素;从优先级队列中取出优先级最高的元素,相当于取出堆顶元素

这优先级应用场景很多:

一:合并有序小文件

有100个小文件,每个文件的大小是100MB,每个文件存储的都是有序的字符串,希望将这100个小文件合并成一个有序的大文件,用到优先级队列

从这100个文件中,各取第一个字符串,放入数组中比大小,把最小的那个字符串放入合并后的大文件中,并从数组中删除,这个最小的字符串来自于13.txt这个小文件,再从这个小文件取下一个字符串,放到数组中,重新比较大小,并且选择最小的放入合并后的大文件,将它从数组中删除,依此类推,直到所有的文件中的数据都放入到大文件中为止

用数组存储从小文件中取出来的字符串,每个从数组中取最小字符串,都需要循环遍历整个数组,不是很高效,可以用优先级队列,从小文件中取出来的字符串放入到小顶堆,那堆顶的元素就是优先级队列队首的元素,即最小的字符串,将这个字符串放入到大文件中,将其从堆中删除,然后再从小文件中取出下一个字符串,放入堆中,循环,可以将100个小文件中的数据依次放入大文件中

二:高性能定时器

定时器中维护了很多定时任务,每个任务都设定了一个要触发执行的时间点。定时器每过一个很小的单位时间,就扫描一遍任务,看是否有任务到达设定的执行时间,如果到达了,拿出执行

最好的方法是用优先级队列,按照任务设定的执行时间,将任务存储在优先级队列中,队列首部存储的是最先执行的任务,定时器只需要拿队首任务的执行时间点,与当前时间点相减,得到一个时间间隔T,定时器设定在T秒之后,再次执行任务,从当前时间点到(T-1)s之间不需要做任务事情

当T秒过去之后,定时器取优先级队列中队首的任务执行,再计算新的队首任务的执行时间点与当前时间点的差值

堆的应用二:利用堆求TOP k

求TOP K问题可以抽象成两类,一类是针对静态数据集合,即数据集合事先确定,不会再变,另一类是针对动态数据集合,数据集合事先并不确定,有数据动态加入集合中

针对静态数据,如何在包含n个数据的数组中,查找前K大数据呢?维护一个大小为K的小顶堆,顺序遍历数组,从数组中取出数据与堆顶元素比较,如果比堆顶元素大,把堆顶元素删除,将这个元素插入到堆中,如果比堆顶元素小,不处理,都遍历完之后,堆中的数据就是前K大数据

一次堆化操作需要O(logK),最坏的情况是n个元素都入堆一次,时间复杂度是O(nlogK)

针对动态数据求得TOP K就是实时TOP K,一个是添加数据,一个是询问当前TOP K

每次询问前K大数据,都一直维护一个K大小的小顶堆,当有数据被添加的时候,与堆顶元素对比

堆的应用三:利用堆求中位数

求动态数据集合中的中位数,即处在中间位置上的数

如果数据个数是奇数,把数据从小到大排列,第n/2+1个数据就是中位数(数据从0开始编号)如果数据个数是偶数的话,中间位置有两个,第n/2个和第n/2+1个数据,可以随意选取一个作为中位数

一组静态数据,中位数是固定的,可以先排序,第n/2个数据是中位数,每次询问中位数的时候,直接返回这个固定的值即可,边际成本会很小,但是,如果我们面对的是动态数据集合,中位数不断在变,如果先排序再询问的话效率就不高了

维护两个堆,一个大顶堆,一个小顶堆,大顶堆存储前半部分数据,小顶堆存储后半部分数据,且小顶堆中的数据都大于大顶堆中的数据,如果有n个数据,n是偶数,从小到大排序,前n/2个数据存储在大顶堆,后n/2个数据存储在小顶堆,这样,大顶堆堆顶元素就是中位数,如果n是奇数,大顶堆存储n/2+1个数据,小顶堆存储n/2个数据

数据是动态变化的,当新添加一个数据的时候,如何调整两个堆,让大顶堆的堆顶元素继续是中位数呢?

如果新加入的数据小于等于大顶堆的堆顶元素,则插入到大顶堆中,否则插入到小顶堆,这时候可能会出现两个顶堆的数据个数不符合前面约定的情况,所以我们可以从一个堆中不停地将堆顶元素移动到另一个堆,这样调整

可以利用两个堆实现动态数据集合中求中位数的操作,插入数据的时间复杂度为O(logn),求中位数只需要返回大顶堆的堆顶元素,时间复杂度是O(1)

利用两个堆不仅可以快速求出中位数,还可以求其他百分位的数据,如何利用两个堆快速求接口的99%响应时间?

99百分位数就是 将一组数据从小到大排列,这个99百分位数就是大于前面99%数据的那个数据,那99%响应时间,如果有100个接口访问请求,每个接口请求的响应时间都不同,然后将响应时间从小到大排列,排在第99的那个数据就是99%响应时间,也叫99百分位响应时间(ps:有n个数据,99百分位数就是第n*99%个数据)

求99%响应时间?

维护两个堆,一个大顶堆,一个小顶堆,当前总数据个数是n,大顶堆中保存 n ∗ 99 n*99% n∗99个数据,小顶堆中保存 n ∗ 1 n*1% n∗1个数据,大顶堆堆顶的数据就是我们要找的99%响应时间。每次插入一个数据的时候,判断这个数据跟大顶堆和小顶堆堆顶数据的大小关系,然后决定插入到那个堆中,如果该数据比大顶堆堆顶元素数据小,插入大顶堆,比小顶堆堆顶元素大,插入小顶堆,为了保持大顶堆中数据占99%,每次插入数据后,重新计算大顶堆和小顶堆中数据个数,是否符合99:1

加入有一个包含10亿个搜索关键词的日志文件,如何快速获取到TOP10最热门的搜索关键词?

可以使用MapReduce,如果我们将处理的场景限定为单机,内存是1GB,因为关键词很多都是重复的,首先统计每个关键词出现的频率,通过散列表、平衡二叉查找树等来记录关键词以及出现的次数

选用散列表,顺序扫描10亿搜索关键词,当扫描到某个关键词时,取散列表中查询,存在,次数+1,不存在,插入到散列表中,表中就存储了不重复的搜索关键词以及次数,再用堆求TOP K的方法,建立一个大小为10的小顶堆,遍历散列表,依次取出每个关键词及次数,与堆顶关键词对比,如果该次数比堆顶关键词次数多,删除堆顶关键词,将这个出现次数更多的关键词加入堆中

如果10亿条搜索关键词中不重复的有1亿条,每个关键词的平均长度是50bit,存储1亿个关键词需要5GB内存空间,而我们只有1GB,无法一次性将所有关键词加入内存中,怎么办?

相同数据经过哈希算法得到的哈希值是一样的,将10亿关键词先通过哈希算法分片到10个文件中,创建10个空文件00,01,02,……09遍历10亿关键词,通过某个哈希算法对其求哈希值,然后哈希值同10取模,得到的结果就是这个搜索关键词应该被分到的文件编号,每个文件都只有1亿关键字,去掉重复的,可能只有1000W个,总大小就是500MB,针对1亿关键词的文件,利用散列表和堆,分别求出TOP10,把10个TOP10放在一起,取这100个关键词中出现次数最多的10个关键词

怎么实现一个访问量非常大的新闻网站,希望将点击量排名TOP10的新闻摘要,滚动显示在网站首页banner上,每隔1小时更新一次?

对每个新闻摘要都计算一个hashcode,建立摘要和hashcode之间的联系,使用map存储,以hashcode为key,新闻摘要为值,每小时一个文件的方式记录下被点击的摘要的hashcode,当一个小时结束后,计算上一个小时的点击top10,将hashcode分片到多个文件,通过对hashcode取模也能算,将相同hashcode放到同一个文件中,针对每个文件取TOP10d hashcode,使用map<hashcode,int>的方式,统计所有的摘要点击次数,在使用小顶堆计算TOP10,针对所有分片计算一个总的TOP10,如果仅展示一个小时的,计算结束,展示全天的,与上次按hashcode合并,取TOP10

堆的应用:如何快速获取到TOP10最热门的搜索关键词?相关推荐

  1. 29 | 堆的应用:如何快速获取到Top 10最热门的搜索关键词?

    为什么评价算法性能是根据时间和空间复杂度,而不是别的参数?是因为计算机结构是冯诺依曼体系,除了输入输出设备和控制器,就剩下运算器和存储器了 问题引入 搜索引擎的热门搜索排行榜功能是如何实现的?搜索引擎 ...

  2. 如何快速获取到Top 10最热门的搜索关键词?

    因为用户搜索的关键词,有很多可能都是重复的,所以我们首先要统计每个搜索关键词出现的频率.我们可以通过散列表.平衡二叉查找树或者其他一些支持快速查找.插入的数据结构,来记录关键词及其出现的次数. 假设我 ...

  3. 网络营销外包专员浅析网站网络营销外包如何快速获取关键词排名

    企业网站正式上线后在激烈的行业竞争中理应思索如何做好网站推广工作,站长可根据企业品牌现状为网站指定相应的网站排名优化策略,为网站更好的呈现和展示在用户面前,争取能够获得搜索引擎和用户的喜爱.那么应该如 ...

  4. html中css路径和xpath路径,6.1 HTML的简单介绍和快速获取XPath和CSS路径

    Web UI 自动化其实就是在页面元素,所以在真正进入页面元素操作之前,我们先认识下我们后面会用到的一些HTML相关知识. HTML的简单介绍 什么是HTML HTML(Hyper Text Mark ...

  5. Python实例 -- 如何快速获取列表中最大的三个元素

    如何快速获取列表中最大的三个元素 最近在做实验,期间需要在一个列表中获取最大的三个元素,自己写的方法复杂度太高,放上大牛的方法,复杂度很低.多看几遍,才能体会到大概的精髓.这道题也是Python的面试 ...

  6. 过年装X神器,快速获取 wifi 密码!

    祝各位朋友们新年快乐,牛年大吉???? 在春节期间,亲朋好友串个门聚一聚是难免的了,作为主人,被问 wifi 密码是常见的事,每次都需要给客人们一遍又一遍的说密码,感觉很low啊.作为程序员,这完全不 ...

  7. JS快速获取图片宽高的方法

    JS快速获取图片宽高的方法 快速获取图片的宽高其实是为了预先做好排版样式布局做准备,通过快速获取图片宽高的方法比onload方法要节省很多时间,甚至一分钟以上都有可能,并且这种方法适用主流浏览器包括I ...

  8. MS SQLSERVER中如何快速获取表的记录总数

    (转自:http://www.cnblogs.com/pingkeke/archive/2006/05/29/411995.html) 在数据库应用的设计中,我们往往会需要获取某些表的记录总数,用于判 ...

  9. java快速获取大图片的分辨率(大图片格式JPG,tiff ,eg)

    问题描述:怎样快速获取一个20MB图片的分辨率? 程序代码: 1 package test; 2 3 import java.awt.Dimension; 4 import java.awt.imag ...

  10. Win7电脑快速获取超级管理员权限的方法

    Win7系统中经常需要超级管理员权限才能删除文件,否则就会提示"需要管理员权限".那么Win7电脑如何快速获取超级管理员权限Win7电脑如何快速获取超级管理员权限?这里就有小编来告 ...

最新文章

  1. web前端面试题集锦三
  2. POJ 1200 Crazy Search 查找有多少种不同的子串(hash)
  3. 华为数据通信产品VRP操作系统的使用
  4. Spring Cloud 入门 之 Zuul 篇(五)
  5. 软考信息安全必备考点
  6. 标定精度_【杰瑞课堂】工业机器人运动精度
  7. 清理SQL Server中的旧代码和未使用的对象
  8. 计算机word实训项目任务说明,计算机项目实训报告怎么写啊
  9. 【java学习之路】(java SE篇)(练习)一些关于面向对象的题目与思考
  10. python代码编辑教程_python教程:pycharm编写代码的方式教学
  11. 在fc6上安装myeclipse全程记录
  12. 【Matlab】数字图像处理_基本原理_1
  13. 搭建FTP站点(Windows)
  14. 李娟计算机学院,李娟(青岛农业大学教授)_百度百科
  15. 微商城分销系统开发方式需求与价格开发周期评估
  16. 美国大学计算机科学gpa,美国大学MS硕士平均GPA是多少分?
  17. 红帽8培训笔记2day
  18. 1.archpr——使用明文攻击bugku——神秘的文件
  19. 线性代数(二十二) :行列式的展开式
  20. 英国全能数学家John Conway因新冠去世,他曾发明风靡一个时代的电脑游戏,还能心算万年历...

热门文章

  1. 摩尔纹是什么?如何消除摩尔纹?
  2. [ExpOS]最新0.0.9.1版本
  3. 合同能源管理服务认证分几个专业?认证依据是什么?
  4. 【SIMULINK】创建及封装子系统
  5. 【2013南京区域赛】部分题解 hdu4802—4812
  6. http请求过程、方式
  7. 基于Matlab的CBF算法图像融合
  8. 1549:最大数 题解(C/C++详细注释版)----线段树模板题
  9. LES DIFFIRENTS DE QUE ET QUEL
  10. HDMI音频提取毛刺解决方法