1.从1亿个IP中找出访问次数最多的IP
首先,因为1G的数据量非常大,一般来说没办法一次性转入内存。所以需要先把文件拆分成许多小文件。可以采用hash取模的方式,将ip地址转换成一个长整数然后对1000取模,模一样的ip放到文件中,这样就得到了1000个小文件。然后,读取每个文件将每个ip放到一个map中,map的value就是ip的访问次数,将访问最多的ip和次数放到另外一个map中。这样,当1000个文件都读取完以后,就有一个有1000条记录的map,里面存储了每个文件最多访问的ip信息。最后,直接从这个map中取出访问次数最多的ip就可以了。
参考:https://blog.csdn.net/linmiansheng/article/details/19290879#commentBox
2.有一个1G大小的文件,里面每一行是一个词,词大小不超过16字节,内存限制是1M,返回频数最高的100个单词。
首先,由于内存限制。因该先拆分大文件,对每个单词取hash值,然后对2000求余,将求余结果相同的单词放到同一个文件中。然后,读取每个文件将每个单词放到一个map中,map的value就是单词出现的频率。然后,对于每个文件的map,用100个单词出现的频率来构建小顶堆,然后遍历后面的数,如果后面的数比堆顶小就忽略这个数,如果比堆顶数大就将堆顶元素替换成这个数。然后重新构建小顶堆,直到遍历完map为止。最后,对所得到的所有数进行归并排序,取前100个。
3.从一亿个数中,找到最大的前m个
方案1:采用最小堆,首先读取前m个数字构建最小堆,构建这个最小堆的时间复杂度为mlogm;然后遍历后面的数,如果后面的元素比堆顶元素小,则忽略这个数,如果比堆顶元素大,就将堆顶元素替换成这个数然后重新构建小顶堆。直到1亿个数全部遍历完为止。这种方案的时间复杂度为 nmlogm。
方案2:采用分治法,就是将一亿个数分成100份,每一份是100万个数,然后找到每份数中最大的10000个数,在这100*10000个数中找到最大的10000个数。在这100万个数中找到最大的10000个数。在每份100万个数中找到最大的10000个数的采用的是快速排序的思想:将数据分成两堆,如果大的堆中数据大于10000个,就对大的堆继续进行快速排序切分成两堆,如果大的那个堆数据还是大于10000,就继续对大的堆进行快速排序切分成两堆,如果大的堆数据小于10000,就对小的堆进行快排切分,然后找到第10000-n个大的数字。通过递归就可以找到前10000个数字了。
参考:
http://www.sohu.com/a/255145095_178889
https://www.cnblogs.com/qlky/p/7512199.html
https://blog.csdn.net/juzihongle1/article/details/70212243
https://blog.csdn.net/hitxueliang/article/details/52153476