如何从一个向量中删除一个元素,当它循环? [英] How to delete an element from a vector while looping over it?

查看:145
本文介绍了如何从一个向量中删除一个元素,当它循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在循环一个带有循环的向量,例如 for(int i = 0; i 。在这个循环中,我检查元素在该向量索引处的条件,如果某个条件为真,我要删除该元素。

I am looping through a vector with a loop such as for(int i = 0; i < vec.size(); i++). Within this loop, I check a condition on the element at that vector index, and if a certain condition is true, I want to delete that element.

如何删除一个向量元素循环而不会崩溃?

How do I delete a vector element while looping over it without crashing?

推荐答案

从STL容器中删除所有元素的惯用方法,谓词是使用删除删除成语。这个想法是将谓词(即对某些元素产生真或假的函数)移动到给定的函数中,例如 pred ,然后:

The idiomatic way to remove all elements from an STL container which satisfy a given predicate is to use the remove-erase idiom. The idea is to move the predicate (that's the function which yields true or false for some element) into a given function, say pred and then:

static bool pred( const std::string &s ) {
  // ...
}

std::vector<std::string> v;
v.erase( std::remove_if( v.begin(), v.end(), pred ), v.end() );

如果你坚持使用索引,你不应该增加每个元素的索引,它没有被删除:

If you insist on using indices, you should not increment the index for every element, but only for those which didn't get removed:

std::vector<std::string>::size_type i = 0;
while ( i < v.size() ) {
    if ( shouldBeRemoved( v[i] ) ) {
        v.erase( v.begin() + i );
    } else {
        ++i;
    }
}

然而,这不仅是更多的代码,更少的惯用(阅读:C ++程序员实际上必须查看代码,而擦除和删除成语立即给出了一些想法发生了什么),但也低得多的效率,因为向量将其元素存储在一个连续的内存块,因此擦除除了向量末端以外的位置也会将删除段后的所有元素移动到新位置。

However, this is not only more code and less idiomatic (read: C++ programmers actually have to look at the code whereas the 'erase & remove' idiom immediately gives some idea what's going on), but also much less efficient because vectors store their elements in one contiguous block of memory, so erasing on positions other than the vector end also moves all the elements after the segment erased to their new positions.

这篇关于如何从一个向量中删除一个元素,当它循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆