最大堆---实现一个简化的搜索提示系统。给定一个包含了用户query的日志文件,对于输入的任意一个字符串s,输出以s为前缀的在日志中出现频率最高的前10条query。



实现一个简化的搜索提示系统。给定一个包含了用户query的日志文件,对于输入的任意一个字符串s,输出以s为前缀的在日志中出现频率最高的前10条query。

由于是分布式系统,假设至少有26台机器,每个机器存储以26个字母开头的query日志文件(如机器1存的是a字母开头的,机器2存的是以b字母开头的……)

每个机器上维护着一张哈希表,对于每条query, 在哈希表表中存放其地址(哈希地址为链式的),并对其进行排序,按频率由高到低进行排序。

当用户进行搜索时,可以很快定位到某台机器,并根据哈希表,返回出现频率最高的前10条query。


提示:

1、可以预处理日志

2、假设query不超过10亿条,每个query不超过50字节。

3、考虑在大查询量的情况下如何实现分布式服务





系统前台
用JS监控input输入框的内容变化,用户输入或者删除字符(输入串的发生变化)就触发异步Javascript提交输入内容到后台,引发后台查询。然后再讲查询结果出现频率最高的前10条query展现给用户提示。

系统后台:
首先有26台服务器分别存储26个字母开头的query。所以首先要设计一个接收用户请求的服务器,这台服务器可以根据用户请求的首字母将查询请求分发给对应26台服务器中的一个(相当于查询请求的路由功能)。
然后就是这26台查询服务器如何设计的问题了。
假设query不超过10亿条,每个query不超过50字节。也就是query文件不超过50G,分在26台机器上也就是每台机器上的query文件不超过2G。
每个机器上维护着一张哈希表,对于每条query, 在哈希表表中存放其地址。收到每个query做hash运算可以找到query对应的地址。对应每个query存储两项信息,即query本身和被查询次数,也就是类似query:times这样的存储格式。
下面做预处理:26台机器都对自身存储的query进行遍历,分别找出a到z开头query出现频率最高的top10,这样的查询一次遍历就能找到,时间复杂度为O(N)。然后对找到的top10在内存中构建一个最小堆。其他非top10的query无需做排序处理。到这里预处理完成。
然后说查询过程,查询分为两类,
1,以给出搜索提示的异步Javascript提交的查询,这种查询直接返回最小堆中的10个query词条即可。
2,用户最终提交的查询(即用户输入完毕点击搜索按钮提交的查询),这种查询的query是用户最终查询的词条,这样的查询应该引起后台存储的对应query频率的变化。当一个query到达的时候,先用hash运算找到他的位置和对应的频率,hash操作时间复杂度是O(1),然后对应的次数+1,然后用这个+1的次数与最小堆中首个元素比较,如果大于最小堆首个元素,与最小堆中首个元素交换,然后最小堆做更新操作,保证最小堆的特性。否则不操作。这样最小堆中维护的10个query始终是这台机器上频率最高的,查询时返回这10个query词条即可。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值