所以我有一个无符号整数的向量(vector<unsigned int>
被称为vector1
)。我有另一个我创建的结构的向量(vector<struct>
被称为vector2
)。 vector<int>
包含一个整数,它是vector<struct>
的索引。例如,让我们说vector<int = {5, 17, 18, 19}
。这意味着vector2.at(5) == vector2.at(vector1.at(0))
。
在结构中,我有一个名为var
的bool变量。在大多数情况下,var
是错误的。我想删除vector1
中var
= true的所有元素。
我做的是:
for (unsigned int i = 0; i < vector1.size(); i++)
{
if (vector2.at(vector1.at(i)).var)
vector1.erase(vector.begin() + i);
}
唯一的问题是它不会删除所有真正的元素。我已经多次运行for循环以删除所有值。这是正确的行为吗?如果不是,我哪里出错?
答案 0 :(得分:3)
您必须使用erase-remove idiom删除矢量中的元素。
v.erase(std::remove(v.begin(), v.end(), value), v.begin);
std::remove
将元素移动到向量的末尾,erase
将从向量中删除元素。
答案 1 :(得分:1)
您可以保留vector1
的临时向量,副本并在for
循环中对其进行迭代,然后从vector1
删除。
答案 2 :(得分:1)
您正在擦除向量中的元素,同时迭代它。因此,当擦除一个元素时,你总是跳过下一个元素,因为你在i
处缩短了向量时增加了i
(如果你使用了一个正确的迭代器循环而不是索引循环)。执行此操作的最佳方法是分离两个opretions,首先“标记”(或者更确切地说,重新排序)要删除的元素,然后从向量中删除它们。
这实际上最好使用erase-remove idiom(vector.erarse(std::remove(...), vector.end())
)完成,该std::remove(_if)
首先使用std::vector::erase
重新组织数据,并在开头使用未删除的元素并返回新结尾范围的,然后可以用来真正删除范围内的那些被删除的元素(实际上只是缩短整个向量),使用{{3}}。使用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
而不仅仅是[]
并牢记两者的含义(特别是前者的开销和后者的“也许不安全”。