STL容器删除操作

简介:

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


删除特定值

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

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

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

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

    1
    c. remove (1963);

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

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

    1
    c.erase(1963);


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

删除判断式

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

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

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

    1
    c.remove_if(badValue);

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

  • 对于标准关联容器

    效率低的remove_copy_if。
    例:

    1
    2
    3
    4
    5
    AssocContainerc;
    ...
    AssocContainergoodValues;
    remove_copy_if(c.begin(),c.end(),inserter(goodValues,goodValues.end()),badValue);
    c.swap(goodValues);

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

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

    错误代码:

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


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

    正确的使用方式:

    1
    2
    3
    4
    5
    6
    7
    8
    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不仅使所有指向被删元素的迭代器失效,也使被删元素之后的所有迭代器失效)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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有效。          

本文转自永远的朋友博客51CTO博客,原文链接http://blog.51cto.com/yaocoder/1199520如需转载请自行联系原作者

yaocoder
相关文章
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
279 9
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
294 5
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
287 2
|
安全 编译器 容器
C++STL容器和智能指针
C++STL容器和智能指针
|
存储 算法 C语言
【C++】详解STL的适配器容器之一:优先级队列 priority_queue
【C++】详解STL的适配器容器之一:优先级队列 priority_queue
|
设计模式 存储 缓存
【C++】详解STL容器之一的deque和适配器stack,queue
【C++】详解STL容器之一的deque和适配器stack,queue
|
存储 算法 C++
【C++】详解STL容器之一的 vector
【C++】详解STL容器之一的 vector
|
算法 C语言 C++
【C++】详解STL的容器之一:list
【C++】详解STL的容器之一:list
|
C++ 容器
C++ STL标准库 《map容器详解》
C++ STL标准库 《map容器详解》
177 0