zoukankan      html  css  js  c++  java
  • STL慎重选择删除元素的

    

    一、要删除容器中有特定值的全部对象

    1、假设容器是vectorstringdeque。则使用erase-remove习惯使用方法。比如:
    vector<int> c;

    c.erase(remove(c.begin(),c.end(),1963),c.end());//删除值是1963的元素

    以下讲一下算法remove

    template<classForwardIterator,class T>

    ForwardIteratorremove(ForwardIterator first,ForwardIterator last,const T& value)

    {

       first = find(first,last,value);

       ForwardIterator next = first;

    return first ==last?first:remove_copy(++next,last,first,value);

    }

    template<classInputIterator,class OutputIterator,class T>

    OutputIteratorremove_copy(InputIterator first,InputIterator last,OutputIterator result,constT& value)

    {

       for(;first != last;++first)

       if (*first != value)

       {

           *result = *first;

           ++result;

    }

    return result;

    }

    移除[first,last)之中全部与value相等的元素。

    这一算法并不真正从容器中删除那些元素(换句话说容器大小并为改变)。而是将每个不与value相等(也就是我们并不打算移除)的元素轮番赋值给first之后的空间。返回值标示出又一次整理后的最后元素的下一位置。

    比如序列{0,1,0,2,0,3,0,4},假设我们运行remove()。希望移除全部0值元素,运行结果将是{1,2,3,4,0,3,0,4}。每个与0不相等的元素。1,2,3,4,分别被复制到第一、二、三、四个位置上。

    第四个位置以后不动,换句话说是第四个位置之后是这一算法留下的残余数据。

    返回值ForwardIterator指向第五个位置。假设要删除那些残余数据。可将返回的迭代器交给区间所在之容器的erase()成员函数。注意,array不适合使用remove()remove_if(),由于array无法缩小尺寸,导致残余数据永远存在。对array而言,较受欢迎的算法是remove_copy()remove_copy_if()

    remove_copy移除[first,last)区间内全部与value相等的元素。它并不真正从容器中删除那些元素,而是将结果拷贝到一个以result标示起始位置的容器身上。

    新容器能够和原容器重叠。但假设对新容器实际给值时,超越了旧容器的大小,会产生无法预期的结果。

    返回值OutputIterator指出被复制的最后元素的下一位置。

    2、假设容器是list。则使用list::remove

    比如:

    list<int> c;

    c.remove(1963);//该成员函数无返回值

    3、假设容器是一个标准关联容器。则使用它的erase成员函数。比如:

    map<int,int>c;

    c.erase(1963);//删除键值是1963的元素

    对于标准关联容器使用不论什么名为remove的操作都是全然错误的。这种容器没有名为remove的成员函数。使用remove算法可能会覆盖容器的值,同一时候可能会破坏容器。

    二、要删除容器中满足特定判别式(条件)的全部对象

    1、假设容器是vectorstringdeque,则使用erase-remove_if习惯使用方法

    比如我们不再从c中删除全部等于特定值的元素。而是删除使以下的判别式返回true的每个对象:

    bool badvalue(int);

    c.erase(remove_if(c.begin(),c.end(),badvalue),c.end());

    2、对于list,则使用list::remove_if。比如:

    c.remove_if(badvalue);

    3、假设容器是一个标准关联容器。则使用remove_copy_ifswap。或者写一个循环来遍历容器中的元素,记住当把迭代器传给erase时,要对它进行后缀递增。比如:

    AssocContainer<int>c;

    AssocContainer<int>goodvalues;

    Remove_copy_if(c.begin(),c.end(),inserter(goodvalues,goodvalues.end()),badvalue);

    c.swap(goodvalues);

    或者

    AssocContainer<int>c;

    for(AssocContainer<int>::iteratori = c.begin();i != c.end();)

    {

       if(badvalue(*i))

           c.erase(i++);

       else

           ++i;

    }

    三、要在循环内部做某些(除了删除对象之外的)操作

    1、假设容器是一个标准序列容器,则写一个循环来遍历容器中的元素,记住每次调用erase时,要用它的返回值更新迭代器。比如:
    ofstream logFile;

    SeqContainer<int>c;

    for (SeqContainer<int>::iteratori = c.begin();i != c.end();)

    {

       if (badvalue(*i))

       {

           logFile << “Erasing” << *i<< ‘ ’;

           i = c.erase(i);//erase的返回值赋给i。使i的值保持有效

    }

    else

    {

       ++i;

    }

    }

    2、假设容器是一个标准关联容器,则写一个循环来遍历容器中的元素。记住当把迭代器传给erase时,要对迭代器做后缀递增。比如:

    ofstream logFile;

    AssocContainer<int>c;

    for(AssocContainer<int>::iterator i = c.begin();i != c.end();)

    {

       if (badvalue(*i))

    {

       logFile<< “Erasing ” << *i << ‘ ’;

       c.erase(i++);

    }

    else

    ++i;

    }

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    微积分
    Docker实战
    使用 Docker 建立 Mysql 集群
    Adaptive Query Optimization in Oracle Database 12c (12.1 and 12.2)
    open()在Linux内核的实现(5)-符号链接目录项的处理
    Red Hat Enterprise Linux上配置SQL Server Always On Availability Group
    Linux进程(作业)的查看和杀死 牛
    为Go语言GC正名-20秒到100微妙的演变史
    汇编语言---GCC内联汇编
    ActiveReports 报表应用教程 (15)---报表换肤
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/4828909.html
Copyright © 2011-2022 走看看