哈希切割top K问题
给一个超过100G大小的log file, log中存着IP地址, 设计算法找到出现次数最多的IP地址?
解题思路:
由于是100G文件,文件太大不能完全加载到内存中去,所以将文件分成1000份,每份大约500M,计算机内存完全可以存下。
那么如何统计相同IP的次数,这里运用哈希切分,使用散列函数(如BKDRHash)依次将所有文件的IP地址转为整型数据IP_KEY,利用IP_KEY%1000(切分的文件数,这里定为1000)再次切分成1000个文件,余数是几就将IP放入几号文件中去(例如余数是7,就放入7号文件),使得相同IP必定进入到相同的文件中去。
最后可以建立一个IP为key,出现次数为value的哈希表,依次读入每个文件的IP,最后统计出现次数最多的IP。
如果要找出TOPK个IP,先对第一个文件的数据建立小堆(大小为K),存入出现次数最多的前K个IP,再依次读入每一个文件,将每一个IP的出现次数与堆中IP次数比较,如果大于其中最小次数的IP,则替换堆顶,并更新堆,依次执行下去,直到1000个文件全部读完,即可找出出现次数最多的前K个IP;
位图应用
给定100亿个整数,设计算法找到只出现一次的整数
在计算机中整数共有4294967295个整数,存储100亿个整数,需要大约40G内存,而利用位图变形,用2个位表示一个整数数据的存储状态(00表示不存在,01表示出现一次,10表示出现多次),表示所有整数只需要1G内存即可,所以可以开辟1G内存的位图,每两位表示一个整数,将100亿个整数插入位图中后,遍历位图,找出状态为01的数据即可;
给两个文件,分别有100亿个整数,我们只有1G内存,如何找到两个文件交集
建立两个位图分别存储两个文件的100亿个整数,位图的每一位表示一个数据的存储状态,再将两个位图按位&,得到的新位图就是两个文件的数据交集;
1个文件有100亿个int,1G内存,设计算法找到出现次数不超过2次的所有整数
建立一个位图,用两个位表示一个int型数据的存储状态(00表示不存在,01表示出现一次,10表示出现2次,11表示出现2次以上),共需要1G内存,将100亿个数据插入位图中后,遍历位图,找出状态为01和10的所有数据;
布隆过滤器+哈希切分
给两个文件,分别有100亿个query,我们只有1G内存,如何找到两个文件交集?分别给出精确算法和近似算法
精确算法:
100亿个query占用内存为40G,可以先将两个文件进行哈希切分,使用散列函数将两个文件的所有query转化为整型key,利用key%100将两个文件转化为两组1000份小文件,每个文件大小平均为40M左右,建立一个哈希表,将第一个文件的数据插入哈希表,用另一个相同编号文件中的每个数据查找是否存在,依次比较,找出交集并记录下来,依次类推,当读完所有文件,就找到了两个文件的交集;
近似算法:
使用布隆过滤器,利用散列函数将字符串转换成整型,将第一组的第一个文件中的数据映射到位图中,一个query映射3个位,再用另一组的相同编号文件去判断一个数据是否存在,三个位都为1时存在交集数据,否则不存在,当读取完所有文件,就可得到两个文件的交集,但可能存在不同数据有重叠映射,所以得出的文件交集并不精确;
如何扩展BloomFilter使得它支持删除元素的操作
布隆过滤器一个数据的key对应多个位,删除数据时不能把对应的所有位直接置位为0,可能有别的数据的key映射同样的位。可以加入引用计数,删除引用计数减1,当减到0时就可以置为0;
如何扩展BloomFilter使得它支持计数操作
将Bloomfilter中的每一位扩展为一个计数器,每次加入数据都要把对应位置加1,每次删除数据把对应位置减1,从而支持计数 操作。计数个数为所有映射到的数据的个数;
将单词用散列函数转化为整型key,对每个文件的所有单词建立闭散列哈希表,将每个文件中的单词及其所对应的文件名和数量插入到哈希表中,再将要每个需要查找的单词在哈希表中查找其对应的文件名即可;
倒排索引
给上千个文件,每个文件大小为1K—100M。给n个设计算法对每个词找到所有包含它的文件,你只有100K内存
将单词用散列函数转化为整型key,对每个文件的所有单词建立闭散列哈希表,将每个文件中的单词及其所对应的文件名和数量插入到哈希表中,再将要每个需要查找的单词在哈希表中查找其对应的文件名即可;