题目:有一个1GB大小的文件, 文件里面每行是一 个词,每个词的大小不超过16B. 内存大小限制是1MB,要求返回频数最高的100个词。
分析解答:
由于文件大小为1GB,而内存大小只有1MB,因此不可能一次把所有的词读入到内存中处理,因此也需要采用分治的方法,把一个大的文件分解成多个小的子文件,从而保证每个文件的大小都小于1MB,进而可以直接被读取到内存中处理。
具体的思路为:
(1)遍历文件,对遍历到的每一个词,执行如下Hash操作: hash(x)%2000, 将结果为i的词存放到文件ai中,通过这个分解步骤,可以使每个子文件的大小大约为400KB左右,如果这个操作后某个文件的大小超过1MB了,那么可以采用相同的方法对这个文件继续分解,直到文件的大小小于1MB为止。
(2)统计出每个文件中出现频率最高的100个词。最简单的方法为使用字典来实现,具体实现方法为,遍历文件中的所有词,对于遍历到的词,如果在字典中不存在,那么把这个词存入字典中(键为这个词,值为1),如果这个词在字典中已经存在了,那么把这个词对应的值加1。遍历完后可以非常容易地找出出现频率最高的100个词。
(3)第2步找出了每个文件出现频率最高的100个词,这一步可以通过维护-一个小项堆来找出所有词中出现频率最高的100个。具体方法为,遍历第一个文件,把第一个文件中出现频率最高的100 个词构建成一个小顶堆。(如果第一个文件中词的个数小于100,那么可以继续遍历第2个文件,直到构建好有100个结点的小顶堆为止)。继续遍历,如果遍历到的词的出现次数大于堆顶上词的出现次数,那么可以用新遍历到的词替换堆顶的词,然后重新调整这个堆为小顶堆。当遍历完所有文件后,这个小顶堆中的词就是出现频率最高的100 个词。(当然这一步也可以采用类似归并排序的方法把所有文件中出现频率最高的100个词排序,最终找出出现频率最高的100个词。)