哈希分治
对于海量数据而言,由于无法一次性装进内存处理,不得不把海量的数据通过 hash 映射的方法分割成相应的小块数据,然后再针对各个小块数据通过 hash_map 进行统计或其他操作。
那什么是 hash 映射呢?简单来说,就是为了便于计算机在有限的内存中处理大数据,我们通过一种映射散列的方式让数据均匀分布在对应的内存位置(如大数据通过取余的方式映射成小数据存放在内存中,或大文件映射成多个小文件),而这种映射散列的方式便是我们通常所说的 hash 函数,好的 hash 函数能让数据均匀分布而减少冲突。(比如统计词频问题把大文件拆分为小文件时,利用哈希映射把把词映射到某一文件时,相同的词一定会被映射到同一个文件中)。
一般的步骤是:先哈希分治/映射,再统计,最后堆/快速排序
题目一
有一个 1G 大小的文件,里面每一行是一个词,词的大小不超过 16 字节,内存限制大小是 1M。返回频数最高的 100 个词。
(1)哈希分治
按先后顺序读取文件,对于每个词 x,执行 hash(x)%5000,然后将该值存到 5000个小文件(记为 x0, x1, ..., x4999)中。如此每个文件的大小大概是 200k 左右。当然,如果其中有的小文件超过了 1M 大小,则可以按照类似的方法继续往下分,直到分解得到的小文件的大小都不超过 1M。
(2)hash_map统计
对每个小文件,采用 hash_map 统计每个文件中出现的词及相应的频率。
(3)堆排序
对每个小文件,取出出现频率最大的 100 个词(可以用含 100 个结点的最小堆)后,再把 100 个词及相应的频率存入文件,这样又得到了 5000 个文件。最后把这 5000 个文件进行归并(可以用归并排序)。