因为用户搜索的关键词,有很多可能都是重复的,所以我们首先要统计每个搜索关键词出现的频率。我们可以通过散列表、平衡二叉查找树或者其他一些支持快速查找、插入的数据结构,来记录关键词及其出现的次数。
假设我们选用散列表。我们就顺序扫描这 10 亿个搜索关键词。当扫描到某个关键词时,我们去散列表中查询。如果存在,我们就将对应的次数加一;如果不存在,我们就将它插入到散列表,并记录次数为 1。以此类推,等遍历完这 10 亿个搜索关键词之后,散列表中就存储了不重复的搜索关键词以及出现的次数。
然后,我们再根据前面讲的用堆求 Top K 的方法,建立一个大小为 10 的小顶堆,遍历散列表,依次取出每个搜索关键词及对应出现的次数,然后与堆顶的搜索关键词对比。如果出现次数比堆顶搜索关键词的次数多,那就删除堆顶的关键词,将这个出现次数更多的关键词加入到堆中。
以此类推,当遍历完整个散列表中的搜索关键词之后,堆中的搜索关键词就是出现次数最多的 Top 10 搜索关键词了。
不知道你发现了没有,上面的解决思路其实存在漏洞。10 亿的关键词还是很多的。我们假设 10 亿条搜索关键词中不重复的有 1 亿条,如果每个搜索关键词的平均长度是 50 个字节,那存储 1 亿个关键词起码需要 5GB 的内存空间,而散列表因为要避免频繁冲突,不会选择太大的装载因子,所以消耗的内存空间就更多了。而我们的机器只有 1GB 的可用内存空间,所以我们无法一次性将所有的搜索关键词加入到内存中。这个时候该怎么办呢?
我们在哈希算法那一节讲过,相同数据经过哈希算法得到的哈希值是一样的。我们可以根据哈希算法的这个特点,将 10 亿条搜索关键词先通过哈希算法分片到 10 个文件中。
具体可以这样做:我们创建 10 个空文件 00,01,02,……,09。我们遍历这 10 亿个关键词,并且通过某个哈希算法对其求哈希值,然后哈希值同 10 取模,得到的结果就是这个搜索关键词应该被分到的文件编号。
本文地址:http://lianchengexpo.xrbh.cn/quote/343.html 迅博思语资讯 http://lianchengexpo.xrbh.cn/ , 查看更多