删除STL容器的元素

版权声明:本文为博主原创文章,可以转载但必须注明出处。 https://blog.csdn.net/nirendao/article/details/85885395

很久以前看《Effective STL》看到的。因为有点杂,整理一下。

1. 删除特定值的元素

1.1 序列容器

如vector,deque,string,其删除特定值的元素的方法是使用 erase-remove 用法。

// 对于vector,deque,string,使用 erase-remove 方法
c.erase(remove(c.begin(), c.end(), 999), c.end());

对于list,则直接可以调用remove方法。

// 对于list,直接用 remove 方法
c.remove(999);

1.2 关联容器

即c是set或者map等类型,则使用erase方法。

// 若c是关联容器,直接用erase()
c.erase(999);

2. 删除满足特定条件的元素

先定义一个函数,所有使该函数返回为true的元素都将被删除:

bool predicate(<container element type>);

2.1 序列容器用remove_if

对于序列容器,vector,deque,string,list,把上面的remove换成remove_if就行了:

// 对于 vector,deque,string,使用 erase-remove_if
c.erase(remove_if(c.begin(), c.end(), predicate), c.end());

// 对于list,直接用 remove_if
c.remove_if(predicate);

2.2 关联容器用循环

关联容器没有提供 remove_if 方法,因此需要写一个循环来遍历。
但是注意,当关联容器中的一个元素被删除时,指向该元素的所有迭代器都将失效。一旦执行了c.erase(it),it就变成无效的值。
为了避免这个问题,要确保在调用erase之前,有一个迭代器指向c中的下一个元素:

AssocContainer<int> c;
for (auto it=c.begin(); it!=c.end(); ) {
    if (predicate(*it))
        c.erase(it++);
    else
        it++;
}

2.3 序列容器用循环删除

对于序列容器,如果也要通过遍历循环来删除特定的元素,则不能使用上面的删除关联容器特定元素的方法,因为对vector,string,deque这类序列容器来说,调用erase不仅会使指向被删除元素的迭代器失效,而且也会使被删除元素之后的所有迭代器失效。
但是,序列容器的erase()函数的返回值会是下一个元素的迭代器。由此可知,具体方法应如下:

SeqContainer<int> c;
for (auto it=c.begin(); it!=c.end();) {
    if (predicate(*it))
        it = c.erase(it); // 序列容器的erase()返回被删除元素的下一个元素的迭代器
    else
        it++;
}

这种方法只对序列容器有效,而对关联容器无效。因为关联容器的erase()方法返回的是void.

(完)

猜你喜欢

转载自blog.csdn.net/nirendao/article/details/85885395