海量数据TOPK算法和TOPN算法

TOPK算法

   TOPK问题是非常经典的处理海量数据的问题。TOPK问题就是给出一堆数,在里面找出最大、最常出现的等一系列问题。

   通常情况下,数量级都是千万级别的,数据量特别大,而且内存使用是有限制的,所以肯定不能先排序,然后再遍历取出K个数。

  堆排序做TopK算法有如下几个特点:

    1、不会改变数据的输入顺序;

    2、不会占用太多的内存空间(事实上,一次只读入一个数,内存只要求能容纳前K个数即可);

    3、由于2,决定了它特别适合处理海量数据。

    此外,还有一点要注意:要找出最小的K个元素使用大顶堆,求最大的K个元素使用小顶堆。小对大,大对小,很好记。

   以下是一些经常被提及的该类问题。

    (1)有10000000个记录,这些查询串的重复度比较高,如果除去重复后,不超过3000000个。一个查询串的重复度越高,说明查询它的用户越多,也就是越热门。请统计最热门的10个查询串,要求使用的内存不能超过1GB。

    (2)有10个文件,每个文件1GB,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。按照query的频度排序。

    (3)有一个1GB大小的文件,里面的每一行是一个词,词的大小不超过16个字节,内存限制大小是1MB。返回频数最高的100个词。

    (4)提取某日访问网站次数最多的那个IP。

    (5)10亿个整数找出重复次数最多的100个整数。

    (6)搜索的输入信息是一个字符串,统计300万条输入信息中最热门的前10条,每次输入的一个字符串为不超过255B,内存使用只有1GB。

    (7)有1000万个身份证号以及他们对应的数据,身份证号可能重复,找出出现次数最多的身份证号。

TOPN问题

  TOPN就是给出一个数组,找出前N个最大的元素。

  比如:

    1. 电商网站中找到每个商品分类下用户点击最多的5个商品是什么等等。

    2. 给定一个几百G的Nginx访问日志文件,取出访问频率在top100的IP。

  问题:有10000个数字,那么求出前n个最大的数?有几种解法

    1. 先给数排序,然后截取前n个。不过这后面10000 - n个数字是不需要排序的。

    2. 利用堆排序。

    3. 先截取前n个数,然后n+1的数和这n个里面的最小数最对比,如果大于最小的数则将该数添加进入这n数里面,再将n里面最小的数剔除,这样到最后输出出来的就是前n最大的数。

       其实TOPN问题可以用分治法解决,这个问题与快速排序类似,快速排序是用一个数对数组进行划分,topN问题则不需完成排序,只需划分出前n个最大的数字即可。所以可以采用快排中partition函数的操作,将每次操作的返回值与N作对比,若比N小则对N及其后续的元素继续进行划分,若比N大则对N及其之前的元素进行划分,直到找出N。

    4. 也可以使用MapReduce来解决TOPN问题。

原文地址:https://www.cnblogs.com/songgj/p/9341125.html