C 如何在1T号码中找到最频繁的号码?

C 如何在1T号码中找到最频繁的号码?,c,algorithm,sorting,find,C,Algorithm,Sorting,Find,如何在1T(即10^12)数字中查找最频繁的数字(整数类型) 我的办公地点是: 我的内存限制为4G(即4·10^9)字节 所有数字都存储在一个文件中作为输入 输出只是一个数字 所有数字(int类型)都存储在一个或多个文件中 文件结构为二进制或行存储 编辑时间:2013.04.22 17:08 感谢您的评论: 加上: -外部存储不受限制。首先请注意,问题至少与外部存储一样严重 因此,解决方案应遵循相同的方法: 排序(使用)和迭代,同时计算每个数字的发生率并查找最大值 散列解决方案:将数字散列

如何在1T(即10^12)数字中查找最频繁的数字(整数类型)

我的办公地点是:

  • 我的内存限制为4G(即4·10^9)字节
  • 所有数字都存储在一个文件中作为输入
  • 输出只是一个数字
  • 所有数字(int类型)都存储在一个或多个文件中
  • 文件结构为二进制或行存储

编辑时间:2013.04.22 17:08 感谢您的评论: 加上:
-外部存储不受限制。

首先请注意,问题至少与外部存储一样严重

因此,解决方案应遵循相同的方法:

  • 排序(使用)和迭代,同时计算每个数字的发生率并查找最大值
  • 散列解决方案:将数字散列到适合内存的存储桶中(注意,相同数字的所有事件都将散列到相同的存储桶中),对于每个存储桶,找到最频繁的数字,并存储它。然后从所有的候选人中选出最好的。
    在这里,您可以对每个bucket进行排序(在内存中)并查找最频繁的数字,也可以创建一个(使用哈希映射,使用不同的哈希函数)来查找bucket中每个项的频率。
    请注意,存储桶被写入磁盘,并一个接一个地加载到内存中,每次只有一小部分数据存储在RAM中
  • 另一种更具可扩展性的方法是使用一个简单的map reduce步骤来计算每个数字的发生次数,然后只需找到其中的最大值:

    map(number):
      emit(number,'1')
    reduce(number,list):
      emit (number, size(list))
    

    剩下的就是找到具有最高值的数字-这可以在线性扫描中完成。

    首先请注意,问题至少和问题一样难

    因此,解决方案应遵循相同的方法:

  • 排序(使用)和迭代,同时计算每个数字的发生率并查找最大值
  • 散列解决方案:将数字散列到适合内存的存储桶中(注意,相同数字的所有事件都将散列到相同的存储桶中),对于每个存储桶,找到最频繁的数字,并存储它。然后从所有的候选人中选出最好的。
    在这里,您可以对每个bucket进行排序(在内存中)并查找最频繁的数字,也可以创建一个(使用哈希映射,使用不同的哈希函数)来查找bucket中每个项的频率。
    请注意,存储桶被写入磁盘,并一个接一个地加载到内存中,每次只有一小部分数据存储在RAM中
  • 另一种更具可扩展性的方法是使用一个简单的map reduce步骤来计算每个数字的发生次数,然后只需找到其中的最大值:

    map(number):
      emit(number,'1')
    reduce(number,list):
      emit (number, size(list))
    

    剩下的就是找到具有最高值的数字-这可以在线性扫描中完成。

    使用哈希表。键是数字,值是计数。O(n)将所有数字插入哈希表O(唯一数字)以查找最频繁的数字。

    使用哈希表键是数字,值是计数。O(n)在哈希表O(唯一数字)中插入所有数字以查找最频繁的数字。

    使用文件系统存储数字计数器有什么好处

    例如,如果编号为uint32,则可以创建65536个目录,每个目录中包含65536个文件。 目录名将是两个高字节的一个数字,文件名-低两个字节。当你们遇到数字X时,你们把它分成两部分,得到文件名,打开那个文件并在里面增加计数器(或者在那个里写1,若文件不存在)

    填充该文件结构后,您可以递归扫描树,查找具有最大值的文件


    这将非常缓慢,但几乎不会占用RAM。

    使用文件系统存储数字计数器有什么好处

    例如,如果编号为uint32,则可以创建65536个目录,每个目录中包含65536个文件。 目录名将是两个高字节的一个数字,文件名-低两个字节。当你们遇到数字X时,你们把它分成两部分,得到文件名,打开那个文件并在里面增加计数器(或者在那个里写1,若文件不存在)

    填充该文件结构后,您可以递归扫描树,查找具有最大值的文件

    这将非常缓慢,但几乎不会吃掉公羊。

    蛮力:

    • 记住=0
    • 重复:
      • 取第一个未标记的数字,并计算其在文件(n1)中的出现次数
      • 将每次出现的数字标记为已读。(用空格f.e覆盖)
      • 如果(n1>记住),记住=n1
      • 暴力:

        • 记住=0
        • 重复:
          • 取第一个未标记的数字,并计算其在文件(n1)中的出现次数
          • 将每次出现的数字标记为已读。(用空格f.e覆盖)
          • 如果(n1>记住),记住=n1

        到目前为止你做了什么吗?使用外部存储器合并排序你能使用外部存储器吗?@SheerFish问题是你有1T(2^40)数字,只有4GB(2^32)空间。你想从2^40个数字中找出最频繁的数字只是为了挑剔,“1T数字”到底是什么意思?它是1TB的数字数据吗?以什么形式?还是从10号到12号?同样,数字本身的格式是什么?到目前为止你做过什么吗?使用外部存储器合并排序你可以使用外部存储器吗?@SheerFish问题是你有1T(2^40)数字,只有4GB(2^32)空间。你想从2^40个数字中找出最频繁的数字只是为了挑剔,“1T数字”到底是什么意思?它是1TB的数字数据吗?以什么形式?还是从10号到12号?同样,数字本身的格式是什么?对于2,如何找到每个存储桶最频繁的数字?如何保证任何存储桶都能放入内存?@Thilo Simple,使用
        hash1(number)
        将数字散列到存储桶中。合适吗?黏液