大数据面试题——查询热门的字符串

本文探讨了在有限内存条件下,如何高效地统计出1000万个查询字符串中出现频率最高的10个字符串的方法。提出了三种解决方案:分治法、字典法和trie树法,并详细分析了每种方法的实现过程及优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述:

搜索引擎会通过日志文件把用户每次检索使用的字符串记录下来,每个查询串的长度为1~255B。假设目前有1000万个记录(这些查询串的复杂度比较高,虽然总数是1000万,但如果出去重复后,那么不超过300万个。一个查询串的复杂度越高,说明查询它的用户越多,也就是越热门的10个查询串,要求使用的内存不能超过1GB.

分析:

每个查询串的最长为255B,1000万个字符串需要占用2.55内存,因此无法将所有的字符串读入内存中处理。

解法:

方法一:分治法

对字符串进行设置一个bash函数,通过这个hash函数把字符串划分到更小的文件中,从而保证每个小文件中的字符串都可以直接加载到内存中处理,然后求出每个文件中出现的次数最多的10个字符串,最后通过一个小顶堆统计出所有的文件中出现次数最多的10个字符串。

解法分析:功能方法可行,但由于要对文件遍历两次且hash函数要被调用1000次所以性能不是很好

方法二:字典法

虽然字符串比较多,但是由于字符串的种类不超过300万个,因此可以考虑把所有字符串出现的次数保存为一个字典中(键为字符串,值为字符串出现的次数)字典所需要的空间为300万*(255+4)=3MB*259=777MB(其中,4表示用来记录字符串出现次数的整数占用4B)。由此可见1G内存空间是足够用的。解题步骤为:

(1)遍历字符串,如果字符串在字典中不存在时,那么直接存入字典中去,键为字符串,值为1.如果已经存在,则相应的值加一。这一步时间复杂度为O(n);

(2)在第一步基础上找出出现频率最高的10个字符串。可以通过小顶堆来完成,遍历字典的前10个元素,并根据字符串出现次数构建一个小顶堆,然后接着遍历字典,只要遍历到的字符串的出现次数大于堆顶字符串的出现次数,就用遍历的字符串替换堆顶的字符串,然后再调整小顶堆;

(3)对所有剩余的字符串都遍历一遍,遍历完成后堆中的10个字符串就是出现次数最多的字符串,这一步时间复杂度为O(Nlog10)

方法三:trie树法

方法二中使用的字典法来统计每个字符串出现的次数。这些字符串有大量相同的前缀时,可以考虑使用trie树来统计字符串出现的次数。可以在树的节点中保存字符串出现的次数,0表示没有出现。具体解法为:在便利的时候,在trie树种查找,如果找到,那么把结点中保存的字符串出现的次数加一,否则为这个字符串构建新的结点,构建完成后把叶子结点中字符串的出现次数置为1。这样遍历完字符串就可以知道每个字符串的出现次数,然后通过遍历这个树就可以找出出现次数最多的字符串。

转载于:https://www.cnblogs.com/circleyuan/p/10350169.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值