C++中vector的remove用法
|
我将从remove的复习开始这个条款,因为remove是STL中最糊涂的算法。误解remove很容易,驱散所有关于remove行为的疑虑——为什么它这么做,它是怎么做的——是很重要的。
这是remove的声明: template<class ForwardIterator, class T> 想想怎么从容器中除去一个元素。唯一的方法是调用那个容器的一个成员函数,几乎都是erase的某个形式,(list有几个除去元素的成员函数不叫erase,但它们仍然是成员函数。)因为唯一从容器中除去一个元素的方法是在那个容器上调用一个成员函数,而且因为remove无法知道它正在操作的容器,所以remove不可能从一个容器中除去元素。这解释了另一个令人沮丧的观点——从一个容器中remove元素不会改变容器中元素的个数: vector<int> v; // 建立一个vector<int> 用1-10填充它 remove并不“真的”删除东西,因为它做不到。 重复对你有好处: remove并不“真的”删除东西,因为它做不到。 remove不知道它要从哪个容器删除东西,而没有容器,它就没有办法调用成员函数,而如果“真的”要删除东西,那就是必要的。 上面解释了remove不做什么,而且解释了为什么它不做。我们现在需要复习的是remove做了什么。 非常简要地说一下,remove移动指定区间中的元素直到所有“不删除的”元素在区间的开头(相对位置和原来它们的一样)。它返回一个指向最后一个的下一个“不删除的”元素的迭代器。返回值是区间的“新逻辑终点”。 举个例子,这是v在调用remove前看起来的样子: 如果我们把remove的返回值存放在一个叫做newEnd的新迭代器中: vector<int>::iterator newEnd(remove(v.begin(), v.end(), 99));这是调用后v看起来的样子: 这里我用问号来标明那些在概念上已经从v中被删除,但继续存在的元素的值。 如果“不删除的”元素在v中的v.begin()和newEnd之间,“删除的”元素就必须在newEnd和v.end()之间——这好像很合理。事实上不是这样!“删除的”值完全不必再存在于v中了。remove并没有改变区间中元素的顺序,所以不会把所有“删除的”元素放在结尾,并安排所有“不删除的”值在开头。虽然标准没有要求,但一般来说区间中在新逻辑终点以后的元素仍保持它们的原值。调用完remove后,在我知道的所有实现中,v看起来像这样: 正如你所见,两个曾经存在于v的“99”不再在那儿了,而一个“99”仍然存在。一般来说,调用完remove后,从区间中删除的值可能是也可能不在区间中继续存在。大多数人觉得这很奇怪,但为什么?你要求remove除去一些值,所以它做了。你并没有要求它把删除的值放在一个你以后可以获取的特定位置,所以它没有做。有问题吗?(如果你不想失去任何值,你可能应该调用partition或stable_partition而不是remove,partition在条款31中描述。) remove的行为听起来很可恶,但它只不过是算法操作的附带结果。在内部,remove遍历这个区间,把要“删除的”值覆盖为后面要保留的值。这个覆盖通过对持有被覆盖的值的元素赋值来完成。 你可以想象remove完成了一种压缩,被删除的值表演了在压缩中被填充的洞的角色。对于我们的vector v,它按照下面的表演: remove检测v[0],发现它的值不是要被删除的,然后移动到v[1]。同样的情况发生在v[1]和v[2]。 vector<int> v; // 正如从前 list<int> li; // 建立一个list 一旦你知道了remove不能“真的”从一个容器中删除东西,和erase联合使用就变成理所当然了。你要记住的唯一其他的东西是remove不是唯一这种情况的算法。另外有两种“类似remove”的算法:remove_if和unique。 remove和remove_if之间的相似性很直截了当。所以我不会细讲,但unique行为也像remove。它用来从一个区间删除东西(邻近的重复值)而不用访问持有区间元素的容器。结果,如果你真的要从容器中删除元素,你也必须成对调用unique和erase,unique在list中也类似于remove。正像list::remove真的删除东西(而且比erase-remove惯用法高效得多)。list::unique也真的删除邻近的重复值(也比erase-unique高效)。 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/vbanglev/archive/2007/02/22/1512521.aspx |
C++中vector的remove用法的更多相关文章
- C++ 中vector的基本用法
//在网上看了好久,自己总结了一下下,第一篇博客,呼呼,学到不少 基本概念 vector容器是一个模板类,可以存放任何类型的对象).vector对象可以在运行时高效地添加元素,并且vector中元素是 ...
- c++中vector类的用法
概括:向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container).跟任意其它类型容器一样,它能够存放各种类型的对象.可以简单的认为,向量是一个能够存放任意类型的动态 ...
- (转载)C++STL中vector容器的用法
vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说vec ...
- thymeleaf中的th:remove用法
一.删除模板片段使用th:remove属性 th:remove的值如下: 1.all:删除包含标签和所有的孩子. 2.body:不包含标记删除,但删除其所有的孩子. 3.tag:包含标记的删除,但不删 ...
- 【转】STL中vector、list、deque和map的区别
1.vector 向量 相当于一个数组 在内存中分配一块连续的内容空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacity()函数 ...
- STL中vector、list、deque和map的区别
1 vector 向量 相当于一个数组 在内存中分配一块连续的内存空间进行存储.支持不指定vector大小的存储.STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capac ...
- 【转】java.util.vector中的vector的详细用法
[转]java.util.vector中的vector的详细用法 ArrayList会比Vector快,他是非同步的,如果设计涉及到多线程,还是用Vector比较好一些 import java.uti ...
- c++中vector的用法详解
c++中vector的用法详解 vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间 ...
- c++ 中vector 常见用法(给初学者)
c++ 中 vector vector有两个参数,一个是size,表示当前vector容器内存储的元素个数,一个是capacity,表示当前vector在内存中申请的这片区域所能容纳的元素个数. ca ...
随机推荐
- Java 图片压缩
package com.wuyu.util; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.Buff ...
- HTML之iframe
iframe:是框架的一种形式. 属性: frameborder=0/1 表示是否显示周围边框 0--否 1--是 width,height:设置的边框宽高,具体数值不需要加单位,也可用百分比 mar ...
- android4.4以上,快捷实现标题栏透明
方法很简单写一个values-v19的文件夹,当安卓版本大于4.4时便会调用该文件夹下的styles.xml文件 结构如图: styles.xml <resources> <!-- ...
- Linux上安装oracle客户端及sqlldr
1.建立oracle的安装目录,一般为/opt/oracle:2.将安装包instantclient-basic-linux.x64-11.2.0.3.0.zip放入到该目录中,并进行解压:unzip ...
- HDU 1237
http://acm.hdu.edu.cn/showproblem.php?pid=1237 表达式计算,方法是中缀转后缀,再计算.中间处理用栈操作 讲解看http://blog.csdn.net/a ...
- 判断安卓和IOS
var u = navigator.userAgent; var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > - ...
- 类和对象 nil/Nil/NULL的区别
iOS-----类和对象,nil/Nil/NULL的区别 iOS中类和对象,nil/Nil/NULL的区别 类与对象的概念 类是对同一类事物高度的抽象,类中定义了这一类对象所应具有的静态属性(属性 ...
- PowerDesigner生成Oracle数据库时,表名会带引号问题
使用PowerDesigner生成数据库建表SQL脚本时,尤其是Oracle数据库时,表名一般会带引号.其实加引号是PL/SQL的规范,数据库会严格按照""中的名称建表,如果没有& ...
- 数组循环:循环多个li 每个li 固定N条数据
PHP代码: $arr = array(1,2,3,4,5,6,7); $x = 1; $y = 0; foreach($arr as $k => $v){ $data[$y][] = $v; ...
- mysql 内存相关文章
简单计算:http://www.mysqlcalculator.com/ 相关文档:http://mingxinglai.com/cn/2016/04/mysql-memory-usage-formu ...