zoukankan      html  css  js  c++  java
  • 海量数据统计topK

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

    思路:

        把这1G的数据一次性全部读入内存是不可能了,可以每次读一行,然后将该词存到一个哈希表里去,哈希表的value是词出现的次数。

        现在的问题是,这个哈希表有多大,能不能装载1M的内存中去。

        假设这1G文件里每个词都不一样,那么最多有不同的1G/1Byte = 1G个词,一个哈希表的节点中包含了单词(key),频率(value),next指针,则内存至少要24bytes * 1G,这显然大大超了。不过如果题目告诉我们顶多有一百万个不同的词,那么 24bytes*1M=24M,对于大多数的机器,这个哈希表是可以建立的,当然此题内存只有1M,连24M的哈希表都装不下。

        因此我们的第一步是将所有的词分到不同的文件中去,相同的词要分到相同的文件中去。这样文件的规模小了,建立的哈希表也就小了。

        将单词的哈希值对5000取模,根据结果将单词分配到5000个文件中去。这样,平均情况下,一个文件中有1G/5000 = 0.2M个词,哈希表基本上能装得下了。

        对每个文件进行hashmap统计,将词与频率写到一个新的文件中,得到5000个新文件。

        维护一个100个节点的最小堆,依次读5000个文件中的每一条记录。如果频率小于堆顶,证明该词比堆里的100个单词频率都低,不可能进top100,舍弃。如果频率大于堆顶,就将该词至于堆顶,然后调用维护函数,维护最小堆的性质。所有的记录遍历完了,最小堆中的单词就是结果。

    总结:

        哈希表的大小不是根据单词的数量,而是根据不同单词的数量。

        最大的topK用最小堆,最小的topK用最大堆。

        算法的时间复杂度:

            分小文件 O(n)

            hashmap统计 O(n)

            维护最小堆 O(n'logK)   n'是不同的单词数,K是topK

  • 相关阅读:
    FSCapture 取色工具(绿色版 )
    Java EE.JavaBean
    Java EE.JSP.内置对象
    Java EE.JSP.动作组件
    Java EE.JSP.指令
    Java EE.JSP.脚本
    21、多态与多态性、内置方法、反射、异常处理
    20、继承的应用、super、组合
    19、property、绑定方法(classmethod、staticmethod)、继承
    18、类
  • 原文地址:https://www.cnblogs.com/johnsblog/p/3945452.html
Copyright © 2011-2022 走看看