【问题标题】:Fastest way to find pair in a vector, remove it while iterating在向量中找到对的最快方法,在迭代时将其删除
【发布时间】:2019-05-15 04:52:17
【问题描述】:

我目前正在研究一种类似于活动选择问题的贪心算法。我有成对的向量(自然数),按第二个值排序。对于每一对,我可能采用最接近的一对(最接近的意思是 (p2.first - p1.second) 是最小的并且 p1.second

下面是例子。每列是对的索引,每一行是对的范围。例如对[0] = [0,3]。在第一次迭代之后,pairs[0] 应该被转换为 [0,9] 并且第二列应该被删除。

【问题讨论】:

  • 您是否尝试计算最大重叠?如果不是,那么您要计算的是什么?换句话说,这似乎是一个XY problem
  • std::vector::erase(iterator) 将返回下一个有效的迭代器。所以你不能使用基于范围的循环。或作为迭代器的开始/结束循环不能在擦除时递增,而是设置为擦除()方法的返回值。我通常会使用一个 while 循环,并在 if() 条件决定擦除时,将迭代器设置为 erase() 方法的返回值,然后在 else 分支中简单地递增迭代器。

标签: c++ algorithm search


【解决方案1】:

很难说做任何事情的“最快方式”是什么。在不完全了解您的约束条件的情况下,即使“足够快”也是有问题的。因此,我将为您提供一些提示,以获取(可能)“更快”的程序;是否足够快由您决定。

首先,您可能想要更改排序标准。您需要先对第一个组件进行排序,然后再对第二个组件进行排序,而不是对第二个组件进行排序(我假设是间隔的末尾)。这样,数组中越早开始的区间越早,在相同开始的区间中,最短的将是第一个。

其次,您可能想要一个辅助数据结构:一个自然排序的数组对,其中每对的第一个组件是任意数字 X,第二个是(排序的)原始数组中第一对的索引从 X 开始的数组。例如,您问题中图像的这个数组将是 {{0, 0}, {4, 1}, {9, 2}}。应该不难看出如何在 O(n) 中构建这个数组,以及如何使用它来加速对原始数组的搜索到一个摊销的 O(1)。

第三,要迭代 std::vector 并毫无问题地删除其元素,您可以使用索引而不是迭代器。然而,这并不是特别有效,因为每个erase 必须向后移动相当多的元素,甚至可能重新分配向量并复制/移动其所有元素。相反,做你现在正在做的事情,并用独特的数字标记你想要删除的那些元素,在你的算法完成后,再检查一次数组并将它们全部删除。以下为伪代码:

displacement = 0
for all elements in the array, do:
    if current element should be removed, then:
        increment "displacement"
    else:
        move current element back "displacement" places

delete last "displacement" elements

编辑:阅读您的评论后,您不需要任何这些东西。只需按照我上面写的方式(即按字典顺序)对数组或对进行排序,然后从中构造另一个对数组,如下所示:

let original vector be A, and the new vector of pairs be B,
t0 = -1
t1 = -1
for all elements in A, do:
    if start time of current element is greater than "t1", then:
         append the pair (t0, t1) to B
         t0 = start time of current element
         t1 = end time of current element
    else:
         t1 = max(t1, end time of current element)
append the pair (t0, t1) to B
remove first element of B (because it is (-1, -1))

(我的方式并不完全优雅,但它完成了工作。)

然后在这个新数组 B 上运行你的成本计算逻辑。这个新数组会更短,并且它的元素之间不会有重叠

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-23
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 2012-11-14
    • 2019-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多