在向量中找到对的最快方法,在迭代时将其删除

时间:2018-12-13 22:19:20

标签: c++ algorithm search

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

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

enter image description here

1 个答案:

答案 0 :(得分:2)

真的很难说什么是“最快的方法”。即使“足够快”也无法准确知道您的约束条件。因此,我将为您提供一些提示,以获取(可能)“更快”的程序;是否足够快取决于您自己决定。

首先,您可能想更改排序标准。无需对第二个组件进行排序(我假设间隔结束),您需要对第一个组件进行排序,然后对第二个组件进行排序。这样一来,一个早点开始的间隔将在数组中更早,而在具有相同开始的间隔中,最短的间隔将是第一个。

第二,您可能需要一个辅助数据结构:自然排序的对数组,其中每对的第一个组成部分是任意数字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上运行成本计算逻辑。这个新数组将更短,并且其元素之间将不重叠