C++ 删除向量中的元素

C++ 删除向量中的元素,c++,vector,erase,erase-remove-idiom,C++,Vector,Erase,Erase Remove Idiom,所以我有一个无符号整数的向量(vector称为vector1)。我创建了一个结构的另一个向量(vector称为vector2)向量保存一个整数,该整数是向量的索引。例如,假设vector必须使用删除向量中的元素 v.erase(std::remove(v.begin(), v.end(), value), v.begin); std::remove将元素移动到向量末尾,而erase将从向量中删除元素。您必须使用从向量中删除元素 v.erase(std::remove(v.begin(), v.

所以我有一个无符号整数的向量(
vector
称为
vector1
)。我创建了一个结构的另一个向量(
vector
称为
vector2
)<代码>向量保存一个整数,该整数是
向量
的索引。例如,假设
vector必须使用删除向量中的元素

v.erase(std::remove(v.begin(), v.end(), value), v.begin);
std::remove
将元素移动到向量末尾,而
erase
将从向量中删除元素。

您必须使用从向量中删除元素

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

std::remove
将元素移动到向量末尾,而
erase
将从向量中删除元素。

您可以保留一个临时向量,复制
向量1
并在
for
循环中对其进行迭代,然后从
向量1

中删除您可以保留一个临时向量,复制
vector1
并在
for
循环中对其进行迭代,然后从
vector1
中删除您正在擦除向量中的元素,同时对其进行迭代。因此,当删除一个元素时,您总是跳过下一个元素,因为您增加了
i
,而刚刚缩短了
i
处的向量(如果使用适当的迭代器循环而不是索引循环,情况会更糟)。最好的方法是将这两种操作分开,首先“标记”(或者说重新排序)要删除的元素,然后从向量中删除它们

在实践中,最好使用(
vector.erarse(std::remove(…),vector.end())
)来完成此操作,它首先使用未删除的元素在开始处重新组织数据,并返回范围的新结尾,然后可以使用它从范围中真正删除这些已删除的元素(有效地缩短了整个向量),使用。使用C++11 lambda,可以非常轻松地表示删除条件:

vector1.erase(std::remove_if(                        //erase range starting here
                  vector1.begin(), vector1.end(),    //iterate over whole vector
                  [&vector2](unsigned int i)         //call this for each element
                      { return vector2.at(i).var; }),  //return true to remove
              vector1.end());                        //erase up to old end

编辑:顺便说一句,如果您真的需要
std::vector::at
而不仅仅是
[]
,请务必记住这两者的含义(尤其是前者的开销和后者的“可能不安全”).

您正在删除向量中的元素,同时对其进行迭代。因此,在删除一个元素时,您总是跳过下一个元素,因为您增加了
i
,而刚刚缩短了
i
处的向量(如果使用正确的迭代器循环而不是索引循环,情况会更糟)。最好的方法是将两种操作分开,首先“标记”(或者更确切地说是重新排序)要删除的元素,然后从向量中删除它们

在实践中,最好使用(
vector.erarse(std::remove(…),vector.end())
)来完成此操作,它首先使用未删除的元素在开始处重新组织数据,并返回范围的新结尾,然后可以使用它从范围中真正删除这些已删除的元素(有效地缩短了整个向量),使用。使用C++11 lambda,可以非常轻松地表示删除条件:

vector1.erase(std::remove_if(                        //erase range starting here
                  vector1.begin(), vector1.end(),    //iterate over whole vector
                  [&vector2](unsigned int i)         //call this for each element
                      { return vector2.at(i).var; }),  //return true to remove
              vector1.end());                        //erase up to old end

编辑:顺便说一句,如果你真的需要
std::vector::at
而不仅仅是
[]
,请务必记住两者的含义(特别是前者的开销和后者的“可能不安全”。

你确定你不是指
if(vector2.at(vector1.at(i)).var)
int
没有成员
var
。是的,很抱歉我在问题中修复了它。你确定你的意思不是
if(vector2.at(vector1.at(I)).var)
int
没有成员
var
。是的,很抱歉我在问题中修复了它。我研究了一下,但我不确定如何将值设置为该元素中var的值。作为一种解决方法,我只是创建了另一个向量,并将适当的元素存储在新向量中。技术上(通常也是实际上)
remove
不必将元素移动到向量的末尾。我对此进行了研究,但我不确定如何将value设置为该元素中var的值。作为一种解决方法,我只是创建了另一个向量,并将适当的元素存储在新向量中。技术上(通常也是实际上)
remove
不必将元素移动到向量的末尾。