我想遍历一个向量并删除某些符合某个条件的元素,例如:
vector<int> myvector;
vector<int>::iterator it;
myvector.push_back(1);
myvector.push_back(2);
myvector.push_back(3);
myvector.push_back(4);
for(it = myvector.begin(); it != myvector.end(); ++it){
if((*it) == 4){
it = myvector.erase(it);
}
}
现在这个工作正常,除非标准删除了上面代码中的最后一项。你怎么避免这种行为?
感谢。
EDIT ------------------------------------
现在我循环的原因是我需要从中删除元素的实际上有4个向量(但标准只在一个向量上):
在这种情况下,这是怎么回事?
vector<int> myvector;
vector<int> myvector2;
vector<int> myvector3;
vector<int> myvector4;
vector<int>::iterator it;
vector<int>::iterator it2;
vector<int>::iterator it3;
vector<int>::iterator it4;
myvector.push_back(1);
myvector.push_back(2);
myvector.push_back(3);
myvector.push_back(4);
(假设myvector2 / 3/4里面有值)
it2 = myvector2.begin()
it3 = myvector3.begin()
it4 = myvector4.begin()
for(it = myvector.begin(); it != myvector.end();){
if((*it) == 4){
it = myvector.erase(it);
it2 = myvector2.erase(it2);
it3 = myvector3.erase(it3);
it4 = myvector4.erase(it4);
}
else{
++it;
++it2;
++it3;
++it4;
}
}
在这种情况下,擦除/删除习惯用法是否有效?
答案 0 :(得分:5)
通常是删除/删除习惯用法,它看起来像这样:
myvector.erase(std::remove(myvector.begin(), myvector.end(), 4), myvector.end());
编辑:重读你的问题,你提到“某些标准”。如果条件不一定仅删除单个值,则可以使用std::remove_if
代替std::remove
,并在仿函数中指定条件。
Edit2:对于处理四个向量的版本,通常的方法是创建一个包含四个相关值的结构,并删除整个结构:
struct x4 {
int a, b, c, d;
// define equality based on the key field:
bool operator==(x4 const &other) { return a == other.a; }
x4(int a_, int b_=0, int c_=0, ind d_=0) : a(a_), b(b_), c(c_), d(d_) {}
};
std::vector<x4> myvector;
myvector.erase(std::remove(myvector.begin(), myvector.end(), x4(4));
同样,如果您的条件比您在比较运算符中可以轻松表达的条件更复杂,则可以使用std::remove_if
代替std::remove
。如果/当您可能需要在不同时间应用不同的标准时,这也很有用。
如果你真的需要将数据保存在并行向量中(例如,你将数据提供给需要单独的,连续数组的外部数据),那么使用循环可能就像替代方案。
答案 1 :(得分:3)
不要使用for循环执行此操作,已经有一个经过良好调试的算法。
myvector.erase(std::remove(myvector.begin(), myvector.end(), 4), myvector.end());
答案 2 :(得分:2)
我认为你应该把循环写成:
for(it = myvector.begin(); it != myvector.end(); )
{
if((*it) == 4)
it = myvector.erase(it);
else
++it; //increment here!
}
因为在您的代码中,如果您找到4
,则会更新it
块本身中的if
,但之后您再次在it
中增加/更新for
{1}}这也是错的。这就是我将其移至else
块的原因,如果您没有找到it
(或您正在搜索的任何值),则会确保4
增加。
另请注意,erase
会返回iterator pointing to the new location of the element that followed the last element erased by the function call。
答案 3 :(得分:0)
erase
通常与remove
一起使用(另请查看erase-remove成语),如下所示
myvector.erase(std::remove(myvector.begin(), myvector.end(), 4), myvector.end());
答案 4 :(得分:0)
for(it = myvector.begin(); it < myvector.end(); ++it){
if((*it) == 4){
it = myvector.erase(it);
}
}
如果it >= myvector.end()
。