stl vector/list如何一边遍历一边删除

这篇文章的遍历删除的效率可能会比较低,更优化的办法请参见如下文章

http://blog.csdn.net/wangeen/article/details/39473029


有时候我们在遍历stl的容器的时候需要删除一些不符合条件的item,这时候我们就要担心iterator是不是因为原始的数据的改变而发生改变,因此往往比较容易出现一些问题,


下面比较一下list 和 vector的两种一边遍历一边删除:
    // list
    list<int> lll;
    // vector
    // vector<int> lll;
   
    lll.push_back(1);
    lll.push_back(2);
    auto tb = lll.begin(), te= lll.end();
    for(;tb!=te;){  // not ++tb here!!!
        printf("%p", &*tb);
        printf("%p", &*(lll.end()));
        if(something()==true){
            tb=lll.erase(tb);
        }else{
            ++tb;
        }
    }


list的能正常通过运行但是vector的却有断错误,问题出在哪里呢? 问题就是在于两个的erase函数的不同

List:
This effectively reduces the list size by the number of elements removed, calling each element's destructor before.

lists are sequence containers specifically designed to be efficient inserting and removing elements in any position, even in the middle of the sequence. Compared to the other base sequence containers (vector and deque), lists are the most efficient container erasing at some position other than the beginning or the end of the sequence, and, unlike in these, all of the previously obtained iterators and references remain valid after the erasing operation and refer to the same elements they were referring before (except, naturally, for those referring to erased elements).

vector:
Because vectors keep an array format, erasing on positions other than the vector end also moves all the elements after the segment erased to their new positions, which may not be a method as efficient as erasing in other kinds of sequence containers (deque, list).

This invalidates all iterator and references to position (or first) and its subsequent elements.


不难发现list erase不会改不原来的iterator, vector 就会改变,因此我们只要在代码里稍微做一点点修改就可以改正这个问题:
for(;tb!=te;)

// change to

for(;tb!=lll.end();),

另外我们也发现 vector 的 erase 需要整个vector 移动,这个代价十分高,所以尽量少用。若排序顺序不是很重要的化,可以和最后的那个item swap,然后删掉最后那个,这样可以显著的提高效率。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值