【问题标题】:Store which elements of a vector to erase存储要擦除的向量的哪些元素
【发布时间】:2013-07-03 20:48:20
【问题描述】:

我有一个向量 V,我想存储这个向量的哪些元素我以后必须删除。

为此,我使用了另一个向量 Y 来存储要删除的 V 元素的迭代器。所以我遍历 Y 以访问我需要在 V 中删除的元素的迭代器。

问题是当你从 V 中删除元素时,Y 中的所有迭代器(指向 V 的元素)都变得无效。

我找不到任何答案,但这似乎很简单,必须有一个简单的解决方法,不是吗?

【问题讨论】:

  • 从向量中删除元素时,使用向后迭代器(不再有解引用问题)

标签: c++


【解决方案1】:

使用V.erase(std::remove_if(V.begin(), V.end(), MyPredicate()), V.end())

【讨论】:

  • 您的谓词决定是否要删除它传递的元素。
  • 决定一个元素是否应该被删除的东西(更多细节见这里:stackoverflow.com/questions/6854039/…
  • 只是在这种情况下谓词并不简单,需要加倍工作(在计算能力方面过于贪婪)
  • 为什么需要双倍的工作?测试你的“被删除”条件的代码必须写在某个地方。无论是写在 for 循环中还是写在 struct MyPredicateoperator() 中,都不会使工作量翻倍,并使您的代码更加通用。
  • 你不是说V.erase(V.begin(), std::remove_if(V.begin(), V.end(), MyPredicate()))
【解决方案2】:

您可以使用std::vector<unsigned> indices 来存储每个元素的索引值。

【讨论】:

  • 这样一来删除索引也会失效。
  • 假设 'indices' 已排序并且没有重复项,则向后迭代索引数组并擦除这些位置的单个元素将起作用,而索引数组保持不变。
【解决方案3】:

指向位置(或第一个)的迭代器、指针和引用 Beyond 无效,所有迭​​代器、指针和引用 位置(或第一个)之前的元素保证继续引用 到他们在调用之前引用的相同元素。

http://www.cplusplus.com/reference/vector/vector/erase/

因此,如果 Y 的元素(迭代器)已排序,您可以向后迭代 Y 并删除 V 中的相应元素。这是有效的,因为当您擦除 V 中的元素时,只有 V 中后面元素的迭代器无效。

【讨论】:

  • 这似乎可行,但请记住 .erase() 返回 下一个迭代器,因此您必须确保并减少它。 this post 也有一些有用的讨论。
  • 不,您不需要擦除的返回值。由于您从末尾开始删除 V 中的元素,因此您永远不会使 Y 中的迭代器无效。
【解决方案4】:

这是关于复杂性的。

您可以将元素从较高的索引擦除到较低的索引,在这种情况下,您的方法会起作用,但是每次您擦除向量的一个元素时,它后面的元素都会被重新定位。这在被擦除元素之后的元素数量中具有线性复杂性,因此我期望某种二次复杂性,或O(number_of_elements * number_of_elements_to_be_erased)

如果删除的数量很高,并且要擦除的元素的索引在整个范围内或多或少均匀分布,则从复杂性的角度来看,更好的解决方案是处理“要删除的元素”的补码抹去”。相反,它将是“要保留的元素”,您可以将应该保留的元素复制到新数组并将其分配给旧数组。这与向量中的元素数量O(number_of_elements)线性

更好的是,如果您可以完全控制实现并且可以将 std::vector 更改为 std::list,那么您可以完全按照您的描述继续进行其余操作,而不会产生不良副作用。在这种情况下,擦除也是高效的,在常量时间内完成,所以整个操作是O(number_of_elements_to_be_erased)

【讨论】:

  • 但是复制不是比删除更昂贵吗?
  • 取决于要删除的#elements,以及它们在哪里。你是对的,在我的分析中,我假设删除的数量很高,并且均匀分布在所有索引中。相应地编辑了答案。
  • @gpalex 假设您的向量很长(例如 = 1000),您应该删除前 10 个元素。这意味着将 1000 个元素重新定位 10 次(10000 次操作)。与此相比,复制意味着只遍历数组一次(1000 次操作)。
  • @gpalex 在 O() 表示法中添加了复杂性以使其更具可读性。
  • 是的,但很大程度上取决于数据
猜你喜欢
  • 1970-01-01
  • 2022-01-13
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
相关资源
最近更新 更多