c++容器使用,C++的容器
c学习笔记10-关联容器-自由-博客公园
c学习笔记X-关联容器一、概述:关联容器和顺序容器的本质区别在于,关联容器通过键存储和读取元素,顺序容器通过元素在容器中的位置顺序存储和访问元素。
1.关联容器支持通过键高效地搜索和读取元素。两种基本的关联容器类型是映射集。map的元素被组织成键-值对:键被用作map中元素的索引,而值表示存储和读取的数据。集合只包含一个键,并且有效地支持关于一个键的存在的查询。
2.一般来说,如果想要有效地存储不同的值集,使用set容器更合适,而map容器更适合需要存储(甚至修改)与每个键相关联的值的情况。在做某种文字处理的时候,可以用set保存要忽略的单词。字典是map的一个很好的应用:单词本身是一个键,它的解释是一个值。
3.关联的容器类型:
Map array:通过键存储和读取元素。
Set是一个大小可变的集合,支持按键快速读取。
Multimap支持相同键出现多次的映射类型。
Multiset支持同一个键出现多次的集合类型。
二、结对类型:
1.pair的创建和初始化:pair包含两个数据值。像容器一样,pair也是一种模板类型。但是,与前面介绍的容器不同,在创建pair对象时,必须提供两个类型名:pair对象中包含的两个数据成员的对应类型名,必须相同。
成对字符串,字符串anon//保存两个字符串
pair string,int word _ count//保存一个字符串和一个int
pair string,vector int line//保存string和vector int如果创建pair对象时没有提供初始化器,则调用默认构造函数用值初始化其成员。因此,anon是包含两个空字符串成员的pair对象,而line存储一个空字符串对象和一个空vector对象。word_count中的int成员的值为0,而string成员被初始化为空string对象。
2.定义时可以为每个成员提供初始化公式:
对字符串,字符串作者(詹姆斯,乔伊斯);3.3.pairs对象的操作:make_pair(v1,v2)用v1和v2值创建一个新的pair对象,其元素类型分别为v1和v2类型。
P1两个pair对象之间的小于运算按字典顺序定义:if p1.first p2.first or!(p2 . first P1 . first)P1 . second p2 . second,返回true。
P1==p2如果两个配对对象的第一个和第二个成员依次相等,则它们相等。该操作使用其元素的==运算符。
P.first返回p中第一个命名的(公共)数据成员。
P.second返回名为p的second的(公共)数据成员。
三。相关容器的公共操作:
1.三种构造函数:
创建一个空容器
//c2必须与c1类型相同
c T C1(C2);//将元素从c2复制到c1
//b和e是表示序列的迭代器
C T c(b,e);//将序列中的元素复制到c2.begin、end、rbegin和rend操作中。
3.对于map容器,value_type不是元素的类型,而是描述键及其关联值类型的pair类型。4.支持交换和赋值操作。但是,关联的容器不提供赋值功能。5.支持清除和擦除操作,但是关联容器的擦除操作返回void类型。6.resize函数不能用于关联容器。四。map类型容器:map是键值对的集合。map类型通常可以理解为一个关联数组:一个键可以作为下标来获取一个值,就像内置数组类型一样。关联的本质是元素的值与特定的键相关联,而不是通过元素在数组中的位置获得。
1.1.map的构造函数:
Map k,v创建一个名为m的空Map对象,它的键和值类型分别是k和v。
图k,v m(m2);创建m2的副本M。m和m2必须具有相同的键类型和值类型。
映射k,v m(b,e);创建一个map类型的对象M来存储迭代器B和e标记的范围内所有元素的副本。元素的类型必须可转换为对常量k,v。
2.键类型的约束:使用关联容器时,其键不仅有一个类型,还有一个相关的比较函数。默认情况下,标准库使用由键类型定义的运算符来比较键。对于键类型,唯一的约束是必须支持运算符,但不要求是否支持其他关系或等式运算。
3.3.map对象的元素是键-值对,也就是说,每个元素包含两个部分:键和由键关联的值。map迭代器返回一个value_type 3354类型的值,这是一个包含const key_type和mapped_type成员的pair对象;下标运算符返回mapped_type类型的值。
4.关联类型:在学习map的接口时,要记住value_type是一个pair类型,它的值成员可以修改,而键成员不可以。
Map,v: key _ type在地图容器中,用作索引的键的类型。
Map,v: mapped _ type在映射容器中,与键关联的值的类型。
Map,v: value _ type是一个pair类型,它的第一个元素的类型是const map K,V :key_type,它的第二个元素的类型是map K,V :mapped_type。
5.向map添加元素:可以使用insert成员实现;或者,先用下标运算符获取元素,再给获取的元素赋值。在这两种情况下,给定的键只能对应一个元素的事实会影响这些操作的行为。与映射键关联的值由value初始化:类类型的元素由默认构造函数初始化,而内置类型的元素初始化为0。
6.6.map:insert的使用:
A.插入单个元素的插入版本使用键值对类型的参数。同样,对于参数是一对迭代器的版本,迭代器必须指向键值对类型的元素。另一个区别是:map容器的插入版本的返回类型接受单个值。当使用下标将新元素添加到地图容器中时,元素的值部分将用value初始化。在添加新的map元素时,使用insert member可以避免使用下标操作符的副作用:不必要的初始化。
B.MAP对象中的给定键只对应于一个元素。如果与您试图插入的元素相对应的键已经在容器中,那么insert将什么也不做。包含一个或一对迭代器参数的insert函数的版本不指示是否或有多少元素被插入到容器中。
C.传递给insert的参数相当笨拙。有两种简化方法:使用make_pair:
word _ count . insert(make _ pair( Anna ,1));或者使用typedef:
或者使用typedef。
typedef映射字符串,int:value _ type valType;
word _ count . insert(valType( Anna ,1));d .插入操作:
e是在m上使用的value_type类型的值,如果key (e.first)不在m中,则插入一个值为e.second的新元素;如果密钥已经存在于m中,则保持m不变。该函数返回一个类型为pair对象,包括一个指向带有关键字e.first的元素的map迭代器,以及一个类型为bool的对象,指示该元素是否被插入。
Beg和end是标记元素范围的迭代器,其中的元素必须是m.value_type类型的键值对。对于此范围内的所有元素,如果其键不在m中,则该键及其关联值将被插入到m中。返回void类型
e是在M上使用的value_type类型的值,如果键(e.first)不在M中,则创建一个新元素,并以迭代器iter为起点搜索新元素的存储位置。返回一个迭代器,它指向m中带有给定键的元素。
7.找到并阅读地图中的元素:
A.下标操作符提供了读取值的最简单方法,但是使用下标有一个危险的副作用:如果键不在map容器中,那么下标操作将插入一个带有键的新元素。
B.m.count(k),返回k在m中出现的次数,对于地图对象,count成员的返回值只能是0或1。Map容器只允许一个键对应一个实例,所以count可以有效地表示一个键是否存在。
C.M. find (k),如果M容器中有k索引的元素,返回指向该元素的迭代器。如果元素不存在,则返回结束迭代器。
8.从地图中删除元素:
A.m.erase(k),删除m中key为K的元素,返回size_type类型的值,表示删除元素的个数(0或1);
B.m.erase(p),从m中删除迭代器P指向的元素,P必须指向m中确实存在的元素,并且不能等于m.end()。返回无效
C.m.erase(b,E),从M开始删除一个范围内的元素,该范围由B和E的迭代器标记,B和E必须在M中标记一个有效范围:即B和E都必须指向M中的元素或最后一个元素的下一个位置。而且B和E要么相等(此时删除的范围为空),要么B指向的元素必须出现在E指向的元素之前,返回void类型
9.map对象的迭代遍历:和其他容器一样,MAP也提供begin和end操作来生成遍历整个容器的迭代器。当迭代器用于遍历map容器时,迭代器指向的元素的键按升序排列。
动词(verb的缩写)集合类型容器:集合容器只是简单键的集合。
1.set不支持下标运算符,并且未定义mapped_type类型。在set容器中,value_type不是pair类型,而是与key_type相同的类型。它们都是指存储在集合中的元素类型。这种差异还表明,存储在集合中的元素只是键,而没有关联的值。与map一样,存储在set容器中的键必须是唯一的,并且不能修改。
2.set容器的定义和使用:用一系列元素初始化set对象,或者在set对象中插入一组元素时,实际上每个键只添加一个元素。
?12345678910//用20个元素定义一个向量,保存从0到9的每个数的两个副本9vector int ivecfor(vector int:size _ type I=0;我!=10;I){ ivec . push _ back(I);ivec . push _ back(I);//每个数字的重复副本}//对于vector中的重复元素,只插入一个。set int iset(ivec.begin()、ivec . end());cout ivec . size()endl;//打印20 cout iset . size()endl;//打印10 /int /int /int 3。向集合中添加一个元素:与map容器的操作一样,带有key参数的insert版本返回一个类型为pair的对象,该对象包含一个迭代器和一个bool值。迭代器指向带有键的元素,bool值指示该元素是否已被添加。使用迭代器对的插入版本返回void类型。
?1234iset.find(1) //返回引用key==1iset.find(11)元素的迭代器//返回迭代器==iset.end()iset.count(1) //返回1iset.count(11) //返回0?14.就像你不能修改map中元素的key部分一样,set中的key是const。当你得到一个指向集合中一个元素的迭代器后,你只能读它,不能写它:
?1234//set_it引用key==1 set int:iterator set _ it=iset . find(1)的元素;* set _ it=11//错误:集合中的键是只读的cout * set _ it endl;//ok:可以读取key /int VI。多映射和多集类型:多集和多映射类型允许一个键对应多个实例。
1.multimap和multiset支持的操作分别与map和set的操作相同,只有一个例外:Multimap不支持下标操作。不能在multimap对象上使用下标操作,因为在这样的容器中,一个键可能对应多个值。
2.添加和删除元素:
A.由于不要求键是唯一的,所以每次调用insert时都会添加一个元素。例如,您可以如下定义一个multimap容器对象,将作者映射到他们的书名。这种映射可以为一个作者存储多个条目:
?123456789//添加带有关键字Barth authors . insert(make _ pair(string( Barth,John ),string(Sot-Weed Factor ))的第一个元素;//ok:添加第二个元素,关键字为Barth authors . insert(make _ pair(string( Barth,John ),string( Lost in the fun house ));1?1b.strong带有密钥参数的tt擦除/tt版本将删除带有此密钥的所有元素,并返回已删除元素的数量。/strong而带有一个或一对迭代器参数的版本只删除指定的元素,返回tt void /tt类型:1?13.在tt多重映射/tt和tt多重集/tt中查找元素:strong在tt多重映射/tt和tt多重集/tt容器中,如果一个键对应于多个实例,这些实例将在容器中彼此相邻存储。/strong
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。