(1)通用解法
1)将所有数据通过哈希函数 pos = key % M,写入M个文件中。(这里的M可以根据内存情况调整)
2)通过HashMap等结构记录每个文件中的情况,再将所有的HashMap结果合并即可
(2)数字型
1>Top K:直接用最大堆(最小的top k)或最小堆(最大的top k)
2>特点:可以根据数据的大小划分到不同文件中(如按1024划分,n/1024=1则划分到第一个,n/1024=3则划分到第三个文件中)
(3)字符串型
1>特点:可以利用类似java中求String的hasCode的方法一样,根据其中的字符来计算哈希值,用求得的哈希值取模即可。
(4)例题
1>寻找热门查询:搜索引擎会通过日志文件把用户每次检索使用的所有串保存起来,每个查询长度为1-255字节。目前有1000万条记录,统计其中最热门的10个查询(1000万个查询重复率很高,去重之后大概300万个,一个查询重复率越高说明越热门)
解答:首先求出所有查询字符串的哈希值,然后对于每个子串x,取hash(x)%1000,按值存储到1000个小文件中;对于每个串,使用trie树或者hashMap统计每个串出现的次数;对于每个文件,找出其中top 10的串,共10*1000 = 10000个串,使用trie树或红黑树或堆找出其中前10即可。
2>给定a、b两个文件,各放50亿个url,每个url各占64个字节,内存限制是4g,找出a、b共同的url
解答:遍历文件a,对每个url,求hash(url)%1000,然后根据哈希值将url分别存储在1000个小文件中,记为a0,a1.....。这样每个小文件的大小就为300M;遍历文件b,采取和a完全相同的方式将url存储在另外1000个小文件中,记为b0,b1.....;因为hasCode获得的方式相同,那么相同的url只可能在对应的2个文件中,如a0 vs b0,a1 vs b1,不对应的文件不可能有相同的url,然后从两个文件中找出相同的即可
3>寻找2.5亿个整数中不重复的整数的个数
解答:将2.5个数哈希到1000个小文件中;然后对每个文件中的数据使用BitMap,从而找出不重复的数;再将所有不重复的数合并即可
4>5亿个整数中查找中位数
解答:将5亿个数哈希到5000文件中;统计每个文件中有多少个数;然后查找第2.5亿个数在哪个文件中;找到文件后,再在文件中确定中位数是哪个