【问题标题】:Efficiently Merging Adjacent Blocks有效合并相邻块
【发布时间】:2012-05-20 00:33:28
【问题描述】:

这就是我想要做的: 我有一个名为 merge() 的例程,它经常被调用。它的任务是合并称为“Block”的数据结构,其内容是由“s_idx”和“e_idx”表示的整数范围,分别表示起始索引和结束索引。相邻块是其范围可以组合成一个新的连续范围的块。例如,范围为 (25,32) 的块 3 和范围为 (33,40) 的块 4 是相邻的,因此可以组合它们的范围以产生新的连续范围 (25,40)。所以最后,将只剩下一个块,将所有单独的块组合起来产生范围 (0,N-1),其中 N 是块的总数。

我的问题是:是否有任何有效的算法来执行这样的操作?

当前的实现使用 O(N^2) 算法,随着块数的增加,该算法会显着减慢。

for( int i=0 ; i<_merge_list.max()-1 ; i++ )
    {
        for( int j=i+1 ; j<_merge_list.max() ; j++ )
        {
            if( _merge_list.exist(i) && _merge_list.exist(j) )
            {
                if( _merge_list[i]->get_end_idx() + 1 ==    _merge_list[j]->get_start_idx() )
                {
                    _merge_list[i]->set_end_idx( _merge_list[j]->get_end_idx() );
                    _merge_list[i]->set_link( _merge_list[j]->get_block_idx() );


                                    perform(_merge_list[i]);

                    _merge_list.remove(j);          
                }
            }
        }

    }   

【问题讨论】:

  • 例程 merge() 从其他处理器接收块,并且在某些特定点,例程将被调用以合并块。当每两个块合并后,将对生成的新块执行一个操作,如以下行所示:perform(_merge_list[i]);
  • 所以块之间随时都可能有间隙。
  • 不,没有限制。
  • 现在我假设正确性,只要它不超过最大可表示的数字。
  • [0,5] 和 [8,12] 不能合并,因为它们不连续。但是,[0,5],[6,7],[8,12] 可以合并如下: [0,5]+[6,7] = [0,7] 然后 [0,7] + [8,12] = [0,12]。但是,最后总是保证它们都可以合并到一个块中,因为所有块都已经可用了。

标签: arrays algorithm data-structures merge theory


【解决方案1】:

您的所有块都保证是连续的吗?如果是这种情况,在 O(N) 时间内找到最小、最大索引然后创建一个最终块应该很简单,否则您可以先对块进行排序然后合并 O(NlogN) + O(N) = O(NlogN)

如果你以排序的方式维护块,合并一个块只需要 O(N) 时间。如果你同时拥有它们,那么你首先对块数组进行排序,然后合并。如果您将它们零碎地获取,则以保持排序顺序的方式合并到块数组中。

【讨论】:

  • 我不太明白你的想法。为了澄清事情,这个例程不会被调用一次,而是在运行时定期调用。此外,在最后一个块到来之前,无法确定 N。因此,出于这个原因,我的代码中使用了动态数组(_merge_list 是动态数组的一个实例)。
  • 非常感谢您的澄清。但是,块根据其 ID 存储在动态数组中。因此,它们始终保持排序。
  • @takwing 如果块总是保持排序,那么你总是可以在 O(N) 时间内合并,只需遍历排序的块列表并合并。
  • 哦..你是对的。我希望有一些更快的 O(log N) 类算法......但是,这个线程仍然对新想法持开放态度......哈哈
  • 当你收到一个块时,如果你知道接收到的块是什么,你可以通过二分查找找到需要添加的位置 O(logn) 后直接合并 O(1)。跨度>
猜你喜欢
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 2016-05-28
  • 2013-06-10
  • 2012-10-19
  • 2012-02-28
  • 2020-01-23
  • 1970-01-01
相关资源
最近更新 更多