【问题标题】:what to choose when dealing with large sequence of input处理大序列输入时选择什么
【发布时间】:2013-03-28 12:33:04
【问题描述】:

我最近偶然发现了一个问题

当每个序列可以有重复的数字并且大小相当大(接近一百万)并且处理的数据类型是Long时,如何找到两个序列的交集。

我考虑过排序和查找交叉点,这不是一个可行的解决方案 我什至考虑过哈希表它不起作用,因为空间考虑必须是最佳的

有人可以提出更好的处理方法吗?

感谢阅读本文

【问题讨论】:

  • 作为@linuxdeveloper,如果你有足够的磁盘空间,gnu sort 可以工作。然后,您可以执行您声明可以执行的排序序列的交集。

标签: algorithm sorting data-structures hashtable


【解决方案1】:

假设 long 是固定大小,比如 64 位。计划一棵深度最大为 64 的部分二叉树。对于第一个序列中的每个数字,您将生长这棵树。所有叶子都出现在深度 64。每个叶子都有两个整数,它们是引用两个序列的计数器。

for each number n in the first list
    current_node = root
    for i ranging from 1 to 64
        if the i-th bit of n is zero
            grow/traverse edge labeled 'zero' from current_node
        else
            grow/traverse edge labeled 'one' from current_node
        set current_node to be at end of this edge
    if the current_node (now at depth 64) is brand new
        set the node's first counter to 1; second counter to zero
    else
        increment current_node's first counter by 1

第二部分是处理第二个列表,而是更新第二个计数器。如果需要,您也可以跳过创建新节点,因为那里不会有任何交叉点。然后遍历整个树,看看两个计数器在哪里都非零。

【讨论】:

    【解决方案2】:

    我认为每个列表包含 2M 个条目的哈希表(因此哈希表负载保持在相当低的水平,为 50% 或更低)是一个不错的选择。如果您使用最简单的实现,则速度快,不是太大,只有 2M*4B(您的 long 是 4 字节长,对吗?)。

    如果列表中的唯一值很少,排序/搜索树将比哈希表更紧凑,但如果唯一数字很多(您需要子/父指针),它将比哈希表大在树节点中,这就是开销)。

    统计数据是什么?

    【讨论】:

      【解决方案3】:

      对我来说,问题归结为:

      • 使用某种数据结构表示稀疏第一个输入
      • 将第二个输入作为键遍历到上一步计算的数据结构中。

      我最初的想法也是哈希表。但是我们需要为每个数字一个节点。 另一位作者已经有了这个想法。

      我的第二个想法是 B+ 树。我们可以使用这棵树映射一个稀疏集。叶子可以包含一系列 nos ......这样,我们可以在寻找与第二个输入集的交集时消耗更多的 cpu 来搜索叶子。您确实支付了内部节点中 b+ 树索引的成本。假设我们不在树中存储重复项……不需要交集。我们可以使用基于位的存储来优化叶子以减少空间。

      【讨论】:

        【解决方案4】:

        该问题声称“排序和查找交集......不是一个可行的解决方案”。但是,从编码的易用性和清晰性的角度来看,排序是最好的解决方案之一。对于任何一次性问题,花 10 分钟编写排序解决方案比花 15 分钟编写散列解决方案或半小时编写特殊树程序更合理。

        在我的旧 PC(AMD Athlon 5000,约 2GHz)上使用下面显示的 python 代码对一百万个双精度进行排序大约需要 1.3 秒,并且可能比当前处理器快四到五倍。在 O(n lg n) 时间内对两个数组进行排序,然后根据问题的要求在 O(n) 时间内查找匹配项,在现代 PC 上可能需要一两秒。

        In [237]: import random
        
        In [238]: v = [random.random() for i in range(1000000)]
        
        In [239]: %time u = sorted(v)
        CPU times: user 1.32 s, sys: 0.00 s, total: 1.32 s
        Wall time: 1.33 s
        

        注意,question #8630965 指的是在 1.168 秒内排序一百万个浮点值。

        【讨论】:

          猜你喜欢
          • 2014-04-02
          • 2020-07-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多