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

1、假设容器是vector、string或deque。则使用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、假设容器是vector、string或deque,则使用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_if和swap。或者写一个循环来遍历容器中的元素,记住当把迭代器传给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<< ‘\n’;

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 << ‘\n’;

c.erase(i++);

}

else

++i;

}

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

STL慎重选择删除元素的的更多相关文章

  1. 【 D3.js 入门系列 --- 2.1 】 关于如何选择,插入,删除元素

    在D3.js中,选择元素的函数有两个:select 和 selectAll . 先说明一下它们的区别: select 是选择所有指定元素的第一个 selectAll 是选择指定元素的全部(以用于后面同 ...

  2. STL容器删除元素的陷阱

    今天看Scott Meyers大师的stl的用法,看到了我前段时间犯的一个错误,发现我写的代码和他提到错误代码几乎一模一样,有关stl容器删除元素的问题,错误的代码如下:std::vector< ...

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

    pre{ line-height:1; color:#f0caa6; background-color:#2d161d; font-size:16px;}.sysFunc{color:#e54ae9; ...

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

    STL中的容器按存储方式分为两类,一类是按以数组形式存储的容器(如:vector .deque):另一类是以不连续的节点形式存储的容器(如:list.set.map).在使用erase方法来删除元素时 ...

  5. 【 D3.js 入门系列 — 2.1 】 选择、插入、删除元素

    1. select 和 selectAll 的区别 在 D3 中,选择元素的函数有两个:select 和 selectAll,它们的使用非常重要.先说明一下它们的区别: select 是选择所有指定元 ...

  6. STL 中 使用迭代器删除元素的问题

    在vector中删除,大家都知道,直接erase的话,这种写法很有问题.因为erase(iter)之后iter指针就变成野指针了,此时继续iter++就会出问题. for(auto iter = v. ...

  7. STL容器迭代过程中删除元素技巧(转)

    1.连续内存序列容器(vector,string,deque) 序列容器的erase方法返回值是指向紧接在被删除元素之后的元素的有效迭代器,可以根据这个返回值来安全删除元素. vector<in ...

  8. 【 D3.js 入门系列 --- 2.1 】 关于怎样选择,插入,删除元素

    本人的个人博客首页为: http://www.ourd3js.com/  ,csdn博客首页为:http://blog.csdn.net/lzhlzz/. 转载请注明出处,谢谢. 在D3.js中,选择 ...

  9. D3.js的v5版本入门教程(第五章)—— 选择、插入、删除元素

    D3.js的v5版本入门教程(第五章) 1.选择元素 现在我们已经知道,d3.js中选择元素的函数有select()和selectAll(),下面来详细讲解一下 假设我们的<body>中有 ...

随机推荐

  1. 11gR2 Database Services for &quot;Policy&quot; and &quot;Administrator&quot; Managed Databases (文件 ID 1481647.1)

    In this Document   _afrLoop=1459311711568804&id=1481647.1&displayIndex=6&_afrWindowMode= ...

  2. unix pwd使用命令

    [语法]:     pwd [说明]:    此命令会显示当前的工作文件夹 []: pwd     这显示当前工作文件夹 版权声明:本文博主原创文章.博客,未经同意不得转载.

  3. HDU 4896 Minimal Spanning Tree(矩阵高速功率)

    意甲冠军: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一 ...

  4. Struts2之—实现自己的结果集的定义ajax

    项目中我们常常遇到这种需求--页面部分刷新.比如:加入用户,转到加入用户页面时,页面自己主动载入了全部部门. 完整流程:选择所属部门,填写username和password,点击"注冊&qu ...

  5. Shell 文字 顶替tomcat星团war包裹

    执行前server造成免费ssh登陆. 修改配置文件不是太大 您可以覆盖原有的配置 profile 简介 bak=/home/wsm/bak webapps=/home/wsm/webapps/WSM ...

  6. vs2010模板修改

     使用visual studio 2010好久了,也遇到了不少问题,下面跟大家分享一些. 模板修改 说明: 主要工具: 以visual studio 2010作为例子,具体目录可能会根据不同的安装目录 ...

  7. UVa 10012 - How Big Is It? 堆球问题 全排列+坐标模拟 数据

    题意:给出几个圆的半径,贴着底下排放在一个长方形里面,求出如何摆放能使长方形底下长度最短. 由于球的个数不会超过8, 所以用全排列一个一个计算底下的长度,然后记录最短就行了. 全排列用next_per ...

  8. Android深入研究Adapter重绘

    一直以来Adapter的使用都仅仅是流于表面,仅仅知道要实现几个抽象的方法,把Adapter设置给某种listView,就能够非常好的工作起来.所谓理解仅仅是建立在主观的猜想上面,认为应该是这样,对, ...

  9. 【日常学习】【欧拉功能】codevs2296 荣誉的解决方案卫队的一个问题

    转载请注明出处 [ametake版权全部]http://blog.csdn.net/ametake欢迎来看看 题目来源:SDOI2008 文章被剽窃非常严重啊 所以以后都带上版权信息 先上题目 题目描 ...

  10. Linux内核分析(五)----字符设备驱动实现

    原文:Linux内核分析(五)----字符设备驱动实现 Linux内核分析(五) 昨天我们对linux内核的子系统进行简单的认识,今天我们正式进入驱动的开发,我们今后的学习为了避免大家没有硬件的缺陷, ...