关联容器和顺序容器有着根本的不同:关联容器中的元素是按关键字来保存和访问的。与之相对,顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的。
关联容器支持高效的关键字查找与访问。两个主要的关联容器类型是map与set。
map
刷题中能用到的基础用法
- 定义初始化及其操作
//定义一个int->string型的map
map<int,string>M;
//添加元素
M[0]="lemon";
//插入元素
M.insert(map<int,string>::value_type(2,"Diyabi"));//插入元素
M.insert(pair<int,string>(1,"Siqinsini"));
M.insert(make_pair<int,string>(4,"V5"));
//取得迭代器首地址
map<int,string>::iterator iter_map = M.begin();
//取得key
int key = iter_map->first;
//取得value
string value = iter_map->second;
cout<<value<<endl;
map1.erase(iter_map);//删除迭代器数据
map1.erase(4);//根据key删除value
int size=map1.size();//元素个数
int isEmpty=map1.empty();//判断空
map1.clear();//清空所有元素
- 遍历方法
for(map<int,string>::iterator iter = map1.begin();iter!=map1.end();iter++)
{
int keyk = iter->first;
string valuev = iter->second;
}
map类容器
map容器中的元素是一些关键字-值(key-value)对:关键字起到索引的作用,值则表示与索引相关联的数据。字典则是一个很好的使用map的例子:可以将单词作为关键字,将单词释义作为值。
map类型通常被成为关联数组。
map关联容器的类型
map :关联数组;保存关键字-值对;数据的存放是有序的
multimap:关键字可以重复出现的map
unordered_map:用哈希函数组织的map;容器中的数据存放是无序的
unordered_multimap:哈希组织的map;关键字可以重复出现
类型map和multimap定义在头文件map中,unordered_map定义在头文件unordered_map中。
所有有序关联容器数据是按关键字的字典顺序进行存储存放的。
一.map容器:
1.pair类型:
在介绍有关map容器的使用之前,我们需要了解名为pair的标准库类型,它定义在头文件utility中。
一个pair保存两个数据成员。类似容器,pair是一个用来生成特定类型的模板。当创建一个pair时,我们必须提供两个类型名,pair的数据成员将具有对应的类型。可以这么认为,一个pair类型的对象,其实存储的是一个键值对(key-value)。
介绍完pair类型后,我们就会对map容器有更深刻的理解,其实map就是存储pair类型对象的容器。
2.map容器的定义:
类似顺序容器,关联容器也是模板。当定义一个map时,必须指明关键字类型又指明值类型。每个关联容器都定义了一个默认构造函数,它创建一个指定类型的空容器。我们也可以将关联容器初始化为另一个同类型容器的拷贝,或是从一个值范围来初始化关联容器,只要这些值可以转化为容器所需类型就可以。
使用insert()函数向map中添加元素时,传入insert函数中的参数类型必须是pair类型。通常,对于想要插入的数据,并没有一个现成的pair对象,我们可以在insert的参数列表中创建一个pair。而使用emplace函数向map中添加元素时,我们只需要将构造pair类型对象需要的数据传入就可以,emplace函数会自动为我们构造好一个pair类型对象添加到map容器当中。
由于map是不包含重复关键字的,因此重复插入一个已存在的关键字元素并不会添加到map容器中。map容器中存储的关键字对应的值还是第一次添加到容器中关键字对应的值。
遍历map容器:
当解引用一个关联容器迭代器时,我们会得到一个类型为容器的value_type的值的引用。对map容器而言,它的迭代器其实指向的是一个pair类型的对象。
我们可以使用迭代器遍历map容器。
使用下标操作:
map和unordered_map容器提供了下标运算符,我们可以通过下标进行访问map中的元素,也可以通过下标向map中添加元素。
map下标运算符接受一个关键字,获取与此关键字相关联的值。如果关键字不再map中,会为它创建一个元素并插入到map中。
当我们要在map容器中查找一个元素时,我们可以使用find函数查找。
删除元素:
同添加元素一样,关联容器并不支持顺序容器的pop_front()和pop_back()操作。
我们可以使用erase()函数删除关联容器中的元素。
二.multimap容器:
和map容器类似,区别在于map容器中的关键字必须是唯一的,对于一个给定的关键字,只能有一个元素的关键字等于它。而multimap对此没有限制,允许多个元素具有相同的关键字。
由于map与multimap很多操作都一样。在此,我只说一下multimap与map使用不同的地方。
1.添加元素:
由于multimap中容器的关键字不必唯一,所以我们可以向multimap中插入多个关键字相同的元素。
2.下标访问:
map是支持下标访问的,使用起来很方便。但是由于multimap中的一个关键字可能对应多个值,所以multimap并不支持下标操作,这里需要注意。
3.查找元素:
在对于允许重复关键字的容器来说,查找元素的过程稍微复杂些,因为一个关键字可能对应多个值,我们需要把这么对应的值都找出来。
如果multimap中有多个元素具有相同的关键字,则这些关键字在容器中会相邻存储。我们可以通过这一特性,将一个关键字对应的多个值全部找出来。
set类容器
set容器中的每个元素只包含一个关键字,可以这么认为,其实set就是一个集合,用来存储同类型的元素。
set关联容器的类型
set : 关键字即值,即只保存关键字的容器
multiset : 关键字可重复出现的set
unordered_set: 无序的set
unordered_multiset: 关键字可以重复出现的无序的set
set和multiset定义在头文件set中,unordered_set定义在头文件unordered_set中。
一.set容器:
1.set容器的定义与初始化:
同map容器,定义set容器时,我们需要指定关键字的类型,即set集合存储的元素的类型。由于set是有序的关联容器,容器内部会按字典顺序自动为元素进行排序,如果我们需要将数据按顺序存储起来,使用set容器是一个非常不错的选择。数据初始化与map类似。
2.添加与删除元素:
同map容器类似。
3.遍历元素:
同map容器类似。我们使用迭代器进行遍历set容器。需要注意的是,同不能改变一个map的关键字一样,一个set中的关键字也是const的。所以,我们只能用一个set迭代器读取元素的值,但不能修改。
4.查找元素:
由于set中存储的只有关键字,所以set容器并不支持下标操作。
set同样可以使用find函数进行对关键字的查找,此时函数返回指向关键字的迭代器。
二.multiset容器:
set和multiset容器区别同map与multimap容器。在此我们不再介绍multiset的相关操作了。