如何将所有指针从一个向量移动到另一个向量?

How to move all the pointers from one vector to another?

本文关键字:向量 一个 移动 另一个 指针      更新时间:2023-10-16

基本上我想做的是删除向量中的一些指针,但我发现在向量中间这样做可能会很慢。

所以我有一个里面已经有数据的向量:

std::vector<Class*> vec1; // This already contains pointers

我将遍历 vec1,并将一些指针添加到另一个向量 (vec2(: vec2.push_back(vec1.at(index))

现在我想做的是像vec1 = vec2这样的事情,但我不知道这是否是更好(有效(的方法。

最好的方法是什么?

我试过了:

  1. 在循环浏览 vec1 时,只需擦除我需要从中删除的内容:

    it = vec1.erase(it)

  2. 在循环遍历 vec1 时,将最后一项移动到实际索引并poping_back

    vec1.at(index) = vec1.back(); vec1.pop_back();

  3. 在循环遍历 vec1 时在指针指向的对象上设置一些属性,而不是使用 std::remove_if

    vec1.erase(std::remove_if(vec1.begin(), vec1.end(), shouldBeRemoved), vec1.end());

  4. 现在我正在尝试生成一个新向量,同时循环遍历 vec1 并添加我想要保留的指针,然后将这个新向量的内容"交换"或"移动"到 vec1。

显然,当以第 4 种方式执行此操作时,指针会失效:(

我很想看看你们对我有什么建议。非常感谢所有愿意提供帮助的人!

您可以使用std::remove_if有条件地从向量中删除项目。该算法会将需要保留的项目转移到前面。随后std::vector::erase调用,以实际删除未移至前面的物品。

这类似于选项 3,但您不需要先设置属性 - 只需使用确定是否应保留项的谓词,并避免两次越过向量。

如果您不想就地执行此操作,但想要填充新向量,那么std::copy_if这样做。

从向量中删除内容应该使用erase remove idiom

这里很好地涵盖了它:https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

基本思想是先移动元素,然后擦除不需要的项目,这比擦除和移动每个单独的元素更快,从示例中完成:

v.erase( std::remove( v.begin(), v.end(), 5 ), v.end() );

但总的来说:如果你的算法中有很多添加/擦除步骤,你应该使用 std::list,其中删除中间的元素要便宜得多。

您的尝试 #2 表明您对元素的顺序不感兴趣。 remove_if会遇到性能问题,因为它会保持您不删除的项目的顺序;这意味着您可以进行大量轮班来维持此顺序。

交换和弹出将遇到不需要重复弹出背面的问题 - 它可以调整矢量大小或执行其他操作。

因此,通过组合这些想法 - 交换"最后一个未换出"(即最后一个第一次,第二个倒数第二个等(,然后在完成后最后擦除最终项目; 你应该有最快的算法。

一些评论表明,复制比交换快;虽然在执行单个复制时是正确的;对于向量,当你多次复制多个元素时;交换会快得多。