STL容器删除操作

接上一篇STL容器的选择继续,为什么要选这个话题,是因为我相信很多人都曾经错用过STL容器的删除,虽然网上也有不少解决方案,但是我觉得真正能深入其本质进行讲解而且给出了完整解决方案的网络资料并不多,所以我替大家从《Effective STL》进行下总结搬运。


删除特定值

  • 连续内存容器(vector、deque或string)使用 erase-remove。
    例:

    c.erase(remove(c.begin(), c.end(), 1963), c.end());

    当c是vector、string或deque时,erase-remove惯用法是去除特定值的元素的最佳方法;

  • 以上方法也适合于list,但是,list的成员函数remove更高效。
    例:

    c.remove(1963);

    当c是list时,remove成员函数是去除特定值的元素的最佳方法。

  • 对于关联容器,解决问题的适当方法是调用erase。
    例:

    c.erase(1963);


    当c是标准关联容器时erase成员函数是去除特定值的元素的最佳方法。

删除判断式

  • 对于序列容器(vector、string、deque和list),我们要做的只是把每个remove替换为remove_if。
    例:

    bool badValue(int x);   //返回x是否是“bad
    c.erase(remove_if(c.begin(), c.end(), badValue), c.end());

    当c是vector、string或deque时这是去掉badValue返回真的对象的最佳方法。

    c.remove_if(badValue);

    当c是list时这是去掉badValue返回真的对象的最佳方法。

  • 对于标准关联容器

    效率低的remove_copy_if。
    例:

    AssocContainerc;
    ...
    AssocContainergoodValues;
    remove_copy_if(c.begin(),c.end(),inserter(goodValues,goodValues.end()),badValue);
    c.swap(goodValues);

    c现在是一种标准关联容器用于容纳不删除的值的临时容器从c拷贝不删除的值到goodValues交换c和goodValues的内容。

    循环迭代删除(注意失效问题)

    错误代码:

    AssocContainer<int> c;
    ...
    for ( AssocContainer<int>::iterator i = c.begin(); i!= c.end();++i)
    {                        
            if (badValue(*i)) c.erase(i);          
    }


    清晰,直截了当而漏洞百出的用于删除c中的每个元素的代码badValue返回真,不要这么做。

    正确的使用方式:

    AssocContainer<int> c;
    ...
    for ( AssocContainer<int>::iterator i = c.begin();    
            i != c.end();                        
            /*nothing*/ ){                         
            if (badValue(*i)) c.erase(i++);       
            else ++i;                                     
    }

    // for循环的第三部分是空的;i现在在下面自增对于坏的值,把当前的i传给erase,然后作为副作用增加i;对于好的值,只增加i。


  • 必须对vector、string和deque进行循环迭代删除采用不同的战略

    (调用erase不仅使所有指向被删元素的迭代器失效,也使被删元素之后的所有迭代器失效)

    for ( SeqContainer<int>::iterator i = c.begin();  i != c.end();)
    {
            if (badValue(*i))
             {
                    logFile << "Erasing " << *i << '\n';
                    i = c.erase(i);             
            }                                  
            else
                    ++i;
    }

    通过把erase的返回值赋给i来保持i有效。          


本文出自 “永远的朋友” 博客,请务必保留此出处http://yaocoder.blog.51cto.com/2668309/1199520

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值