c++如何遍历删除map/vector里面的元素

新技能Get!

问题

对于c++里面的容器, 我们可以使用iterator进行方便的遍历. 但是当我们通过iterator对vector/map等进行修改时, 我们就要小心了, 因为操作往往会导致iterator失效, 之后的行为都变得不可预知. 比如:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> a = {12, 23, 34, 45, 56, 67, 78, 89};

    for (auto iter = a.begin(); iter != a.end(); ++iter) {
        if (*iter > 30) {
            a.erase(iter);
        }
    }

    for (const auto &element : a) {
        cout<<element<<endl;
    }

    return 0;
}

输出:

12
23
45
67
89

cplusplus的reference里对 std::vector::erase 的描述是:

Iterators, pointers and references pointing to position (or first) and beyond are invalidated, with all iterators, pointers and references to elements before position (or first) are guaranteed to keep referring to the same elements they were referring to before the call.

只有删除元素前面的iterator还保持有效, 之后的遍历行为不可预知.

解决方案

对于vector, erase会返回下一个iterator, 因此我们可以使用如下的方法:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
    vector<int> a = {12, 23, 34, 45, 56, 67, 78, 89};

    auto iter = a.begin();
    while (iter != a.end()) {
        if (*iter > 30) {
            iter = a.erase(iter);
        }
        else {
            ++iter;
        }
    }

    for (const auto &element : a) {
        cout<<element<<endl;
    }

    return 0;
}

输出:

12
23

  

对于map, 删除iterator只会影响当前的iterator, 因此使用for循环就够了, 比如:

#include <iostream>
#include <map>

using namespace std;

int main()
{
    map<int, int> a = {{1, 12}, {2, 23}, {3, 34}, {4, 45}, {5, 56}, {6, 67}};

    for (auto iter = a.begin(); iter != a.end(); ++iter) {
        if (iter->second > 30) {
            a.erase(iter);
        }
    }

    for (const auto &element : a) {
        cout<<element.first<<" : "<<element.second<<endl;
    }

    return 0;
}

输出:

1 : 12
2 : 23

  但是更推荐的做法是在erase前让iterator指向下一个元素

#include <iostream>
#include <map>

using namespace std;

int main()
{
    map<int, int> a = {{1, 12}, {2, 23}, {3, 34}, {4, 45}, {5, 56}, {6, 67}};

    auto iter = a.begin();
    while (iter != a.end()) {
        if (iter->second > 30) {
            a.erase(iter++);
        }
        else {
            ++iter;
        }
    }

    for (const auto &element : a) {
        cout<<element.first<<" : "<<element.second<<endl;
    }

    return 0;
}

输出:

1 : 12
2 : 23

  

参考资料

http://stackoverflow.com/questions/4645705/vector-erase-iterator

http://stackoverflow.com/questions/4600567/how-can-i-delete-elements-of-a-stdmap-with-an-iterator

c++如何遍历删除map/vector里面的元素

时间: 2024-07-31 20:20:37

c++如何遍历删除map/vector里面的元素的相关文章

Java遍历List,Map,Vector,Set的几种方法

关于list,map,set的区别参考http://www.cnblogs.com/qlqwjy/p/7406573.html 1.遍历list @Test public void testList() { List<Integer> list = new ArrayList<Integer>(); list.add(1); list.add(2); System.out.println("-------------------list------------------

Java 循环遍历删除set list中的元素

删除List和Set中的某些元素 错误代码的写法: Set<String> set = new HashSet<String>(); set.add("aaaaaa"); set.add("bbbbbb"); set.add("cccccc"); set.add("dddddd"); set.add("eeeeee"); set.add("ffffff"); se

map/vector遍历删除

map遍历删除 1 map<int, vector<int>>::iterator it = g_map.begin(); 2 for (; it != g_map.end(); /*it++*/) 3 { 4 g_map.erase(it++); 5 } vector遍历删除 1 vector<int>::iterator iter = vec.begin(); 2 while (iter != vec.end()) 3 { 4 if(*iter == 1) 5 {

map,vector 等容器内容的循环删除问题(C++)

map,vector 等容器内容的循环删除问题(C++) map,vector等容器的循环删除不能用普通的方法删除: for(auto p=list.begin();p!=list.end();p++) list.erase(p); 类似的方式,会出错的,不信你调试试试 :) 这里使用了一个` iterator` 的一个自增/自减 ,来巧妙的实现了, 删除当前的`iterator,` 但是有给当前的`iterator`赋值为其下一个的操作,不至于删除后,当前的 `iterator` 就失效了!

stl map高效遍历删除的方法 [转]

for(:iter!=mapStudent.end():) { if((iter->second)>=aa) { //满足删除条件,删除当前结点,并指向下面一个结点 mapStudent.erase(iter++): } else { //条件不满足,指向下面一个结点 iter++: } } 这种删除方式也是STL源码一书中推荐的方式,分析 mapStudent.erase(iter++)语句,map中在删除iter的时候,先将iter做缓存,然后执行iter++使之指向下一个结点,再进入er

STL容器的遍历删除

STL容器的遍历删除 今天在对截包程序的HashTable中加入计时机制时,碰到这个问题.对hash_map中的每个项加入时间后,用查询函数遍历hash_map,以删除掉那些在表存留时间比某个阈值长的表项(当然这个函数是应该运行在另起一个线程上的),但是在按照下面的方法对hash_map(用迭代器)遍历删除时,当找到第一个满足删除条件的元素并将其删除后,程序将提示非法: for(list<int>::iterator iter = m_map.begin(); iter != m_map.en

STL中用erase()方法遍历删除元素?.xml

pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9;font-style:italic;font-weight:bold;} .selfFuc{color:#f1f9be;} .bool{color:#69305e;} .condition{color:#628698;font-weight:bold;} .key{color:#e336b6;} .

Set,List,Map,Vector,ArrayList的区别(转)

JAVA的容器---List,Map,Set Collection ├List │├LinkedList │├ArrayList │└Vector │ └Stack └Set Map ├Hashtable ├HashMap └WeakHashMap Collection接口  Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些 Collection允许相同的元素而另一些不行.一些能排序而另一些不行.Java

map/vector erase

问题核心:erase之后迭代器是否失效 vector调用erase之后,该迭代器之后的迭代器都失效: map调用erase之后,其他迭代器并不会失效. 1 vector<int> vecData; 2 for (typeof(vecData.begin()) it; it != vecData.end();) 3 { 4 if (*it == 1) 5 { 6 it = vecData.erase(it); 7 //vv.erase(it++); //vector erase之后,it迭代器后