写在前面:

关联容器(Associative containers) [əˈsəʊʃiətɪv]


标准库容器类型:
1、顺序容器
比如:vector、list、deque、forward_list(C++11)等。
2、关联容器
关联式容器也是用来存储数据的,与顺序容器不同的是,其里面存储的是
<key, value> 结构的键值对,在 数据检索时比序列式(也就是顺序)容器效率更高。

两者之间的差别: 关联容器通过键(key)存储和读取元素顺序容器则通过元素在容器中的位置存储和访问元素且关联式容器大部分和顺序容器相同 比较特别的地方就是关联容器支持键的使用

键值对
用来表示具有一一对应关系的一种结构,该结构中一般只包含两个成员变量key和value,key代表键值, value表示与key对应的信息

关联容器共享大部分顺序容器的操作 但是关联容器不提供

front、push_front、pop_front、back、push_back 以及pop_pack操作

关联容器可以支持

begin、end、rbegin、rend操作

同时关联容器还有以下和顺序容器公共的构造函数

C<T> c;//创建一个空的容器
C<T> c1(c2);//用c2来拷贝构造c1 ,前提是c2必须和c1的类型相同
C<T> c(b,e);//将序列中的元素复制到c中 b和e是表示序列的迭代器


关联容器支持通过键来高效地查找和读取元素 两个基本的关联容器的类型是

map set

map 的元素以 键 – 值 (key --value) 对的形式组织, 键用在map中的索引 而值表示所存储和读取的数据

set 仅包含一个值 并有效的支持某个值是否存在的查询

注:
如果希望有效的存储不同值的集合 那么使用set容器比较合适
map容器则更使用于需要存储、修改 每个键所关联的值的情况
比如说map可以用来实现一个简单的字典
map 和set 类型的对象所包含的元素都具有不同的键值 不允许为同一个键 添加第二个元素 也就是一个key 不能对应两个不同的value

如果一个键必须对应多个实例 则需要使用multimpmultiset
multimap :支持同一个键多次出现的map类型
multiset :支持同一个键多次出现的set类型

关联容器也支持很多顺序容器也提供相同的操作 此外 还提供 管理或只用键的特殊操作

map 关联数组 元素通过键来存取和读取
set 大小可变的集合,支持通过键实现的快速读取
multimap 支持同一个键多次出现的map类型
multiset 支持同一个键多次出席那的set类型

这次的博客主要来整理map的相关知识要点!

1. 头文件 <map>

2. map:

1.map是关联容器它按照特定的次序(按照key来比较)存储由键–key和值–value组合而成的元素。 (有序)
2. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值key关联的内容。键值 key和值value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起, 为其取别名称为pair: typedef pair value_type;
3.在内部,map中的元素总是按照键值key进行比较排序的。
4. map中通过键值访问单个元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行 直接迭代(即对map中的元素进行迭代时,可以得到一个有序的序列)。
5.map支持下标访问符,即在[ ]中放入key,就可以找到与key对应的value
6. map通常被实现为二叉搜索树(更准确的说:平衡二叉搜索树(红黑树))。
注意:
关于 pair 对象就不再这里重复的介绍了,稍微的提一下
pair 也是一种类模板 ,这个类将一对值耦合在一起,这些值可能是不同类型的 ,单个值可以通过其公共成员 first 和 second 访问。
因此这里说的 key 和 value 也就是 pair 对象中的 公共成员 first 和 second

3. map类型

脑子里记住这个不是地图了哟!
map 是 "键–值对"的集合
map类型通常可理解为关联数组
可使用 "键"作为下标来获取一个值,正如内置数组类型一样 而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。

4.模板参数

key: 键值对中key的类型
T: 键值对中value的类型
Compare: 比较器的类型,map中的元素是按照key来比较的,缺省情况下按照 less (小于)来比较,一般情况 下(内置类型元素)该参数不需要传递,如果无法比较时(自定义类型),需要用户自己显式传递比较规则 (一般情况下按照函数指针或者仿函数来传递)
Alloc:通过空间配置器来申请底层空间,不需要用户传递,除非用户不想使用标准库提供的空间配置器 注意:在使用map时,需要包含头文件。

5. 容器属性

关联容器中的元素由它们的key作为引用而不是他们在容器中的绝对位置
容器中所有的元素总是有着严格的顺序,所有插入的元素都按此顺序都有确定的位置
容器中的任何两个元素都不能具有等效的key. 也就是key不能相同

6. map对象的定义

要使用 map 对象,则必须包含 map 头文件。在定义 map 对象时,必须分 别指明"键"和"值"的类型(value type)
例如 :定义键和值都是string 类型的 map对象。

#include<map>
#include<string>
int main()
{map<string,string> m;//键索引是 string 类型的 关联的值是 string 类型的return 0;
}

7. map的构造函数

________________________________函数声明 __________________________说明
map<k, v>m; 创建一个名为 m 的空 map 对象,其键和值的类型分别为 k 和 v
map<k, v> m(m2); 创建 m2 的副本 m也就是用m2来拷贝构造m,m 与 m2 必须有相同的键类型和值类型
map<k, v> m(b, e); 使用存储迭代器 b 和 e 标记的范围内所有 元素的副本来创建m。元素的类型必须能转换为 pair<const k, v>

示例:

void Test1()
{map<string,string>m;//创建一个空的map对象 m.insert(pair<string,string>("helloworld!","你好世界!"));//插入数据map<string, string> m1(m);//拷贝构造map<string, string> m2(m.begin(), m.end());//使用迭代器进行构造for (auto e : m){cout << e.first << " " << e.second << endl;}for (auto e : m1){cout << e.first << " " << e.second << endl;} for (auto e : m2){cout << e.first << " " << e.second << endl;}
}

8. map的迭代器

函数声明 功能简介

iterator begin () 返回第一个元素的位置
iterator end () 返回最后一个元素的下一个位置
const_iterator begin () const 返回第一个元素的const迭代器
const_iterator end () const 返回最后一个元素下一个位置的const迭代器
reverse_iterator rbegin() 返回第一个元素位置的反向迭代器即rend
reverse_iterator rend() 返回最后一个元素下一个位置的反向迭代器即 rbegin
const_reverse_iterator rbegin() const 返回第一个元素位置的const反向迭代器即rend
const_reverse_iterator rend() const 返回最后一元素下一个位置的反向迭代器即rbegin

大家会发现其实这个和我们之前的vector的迭代器没有多大的差别不过就是多了一个 const 的反向迭代器,用法和vector是差不多的。

做几个简单的示例:假设map对象里的值,我们事先是已经插入好了的。

 map<int, string>m;m.insert(pair<int, string>(1001, "小明"));m.insert(pair<int, string>(1003, "小红"));m.insert(pair<int, string>(1002, "小花"));m.insert(pair<int, string>(1000, "小花"));Test2(m);
普通正向迭代器遍历修改
 cout << "普通正向迭代器遍历" << endl;map<int, string>::iterator mite = m1.begin();while (mite != m1.end()){cout << mite->first << " " << mite->second << endl;++mite;}

注意:
这里再对map对象的 first 和 second 访问是使用的是 " - >" --箭头操作符
这里大家会发现map里面的是已经排好序了的,会默认把键值小的排在前面,是一个升序的排列,相对于int类型的值就会直接进行比较而 string 类型或者别的是按ASCCI码来比较如以下:

普通反向迭代器遍历修改
 cout << "普通反向迭代器遍历" << endl;map<int, string>::reverse_iterator rmite = m1.rbegin();while (rmite != m1.rend()){rmite->second = "李飞";cout << rmite->first << " " << rmite->second << endl;++rmite;}

const 正向迭代器遍历
 cout << "const迭代器遍历" << endl;map<int, string>::const_iterator cite = m1.begin();while (cite != m1.end()){cout << cite->first << " " << cite->second << endl;++cite;}

const反向迭代器遍历
 cout << "const反向迭代器遍历" << endl;map<int, string>::const_reverse_iterator crite = m1.rbegin();while (crite != m1.rend()){cout << crite->first << " " << crite->second << endl;++crite;}

范围for 与 auto 关键字遍历(推荐使用)

其实这样遍历还是比较麻烦的,相比有两种比较简约而又方便的遍历方式推荐给大家,但是他们的底层还是使用的相关迭代器进行实现的

范围 for 遍历
void Test4(map<int,string> &m)
{cout << "范围 for遍历" << endl;for (auto e : m){cout << e.first << " " << e.second << endl;}
}

auto 自动识别迭代器遍历
void Test5(map<int, string> &m)
{cout << "auto关键字的使用" << endl;auto mite = m.begin();while (mite != m.end()){cout <<mite->first << " " << mite->second << endl;++mite;}
}

9. map 对象中元素的修改

函数声明 功能简介
pair<iterator,bool> insert ( const value_type& x ) 在map中插入键值对x,注意x是一个键值对,返回 值也是键值对:iterator代表新插入元素的位置, bool代表释放插入成功
iterator insert ( iterator position, const value_type& x ) 在position位置插入值为x的键值对,返回该键值对 在map中的位置,注意:元素不一定必须插在 position位置,该位置只是一个参考
template void insert ( InputIterator first, InputIterator last ) 在map中插入[first, last)区间中的元素
void erase ( iterator position ) 删除position位置上的元素
size_type erase ( const key_type& x ) 删除键值为x的元素
void erase ( iterator first, iterator last ) 删除[first, last)区间中的元素
void swap ( map<Key,T,Compare,Allocator>& mp ) 交换两个map中的元素
void clear ( ) 将map中的元素清空 iterator find ( const key_type& x )
const_iterator find ( const key_type& x ) const 在map中插入key为x的元素,找到返回该元素的位 置的const迭代器,否则返回cend
size_type count ( const key_type& x ) const 返回key为x的键值在map中的个数,注意map中 key是唯一的,因此该函数的返回值要么为0,要么 为1,因此也可以用该函数来检测一个key是否在 map中
insert 插入一个数据

这里的插入肯定是插入一个 pair 对象,那么请看示例;

 map<int, string> m;pair<int, string> p1(2, "two");m.insert(pair<int, string>(1, "one"));m.insert(p1);for (auto e : m){cout << e.first <<" "<<e.second << endl;}

注意
在一个map对象中 key 的值是唯一的,是不允许插入两个相同的 key ,相同的key 所对应的value也无法插入

erase 删除一个数据
 map<int, string>m;m.insert(pair<int, string>(1, "one"));m.insert(pair<int, string>(2, "two")); m.insert(pair<int, string>(3, "three"));auto a = m.begin();m.erase(a);//删除迭代器位置的元素m.erase(3);//删除 key 为3的元素 即 first=3 的数据

交换两个map对象

10. map的大小容量以及 [ ]

函数声明 功能简介
bool empty ( ) const 检测map中的元素是否为空,是返回true,否则 返回false
size_type size() const 返回map中有效元素的个数
mapped_type& operator[] (const key_type& k) 返回去key对应的value

注意:
虽然 key 不能修改但是 value是可以修改的,也可以通过 [ key ]来访问对应的 value 或者修改:
如:

STL-关联式容器 map相关推荐

  1. STL关联式容器—map的使用

    一.map简介: map是关联容器,它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元素. 在map中,键值key通常用于排序和惟一地标识元素,而值value中存储与此键值 ...

  2. STL——关联式容器

    一.关联式容器 标准的STL关联式容器分为set(集合)/map(映射表)两大类,以及这两大类的衍生体multiset(多键集合)和 multimap(多键映射表).这些容器的底层机制均以RB-tre ...

  3. STL关联式容器详解

    STL关联式容器类别 1. map 定义在 头文件中,使用该容器存储的数据,其各个元素的键必须是唯一的(即不能重复),该容器会根据各元素键的大小,默认进行升序排序(调用 std::less). 2. ...

  4. C++ STL : 模拟实现STL中的关联式容器map和set

    目录 关联式容器 键值对 底层红黑树的改造 仿函数 红黑树的迭代器 完整代码 set set的文档介绍 set的实现 map map的文档介绍 map的实现 operator[] 完整代码 multi ...

  5. C++(STL):29 ---关联式容器map 迭代器

    无论是前面学习的序列式容器,还是关联式容器,要想实现遍历操作,就必须要用到该类型容器的迭代器.当然,map 容器也不例外. C++ STL 标准库为 map 容器配备的是双向迭代器(bidirecti ...

  6. C++(STL):28 ---关联式容器map用法

    作为关联式容器的一种,map 容器存储的都是 pair 对象,也就是用 pair 类模板创建的键值对.其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int.double 等) ...

  7. 关联式容器(map,set,multimap,multiset)

    关联式概念 STL中的部分容器,比如:vector.list.deque.forward_list(C++11)等,这 些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面存储的是元素本身. ...

  8. 关联式容器---map和set

    map和set 1 关联式容器 2 键值对 3 树型结构的关联式容器 3.1 set 3.1.1 set 的介绍 3.1.1 set 的使用 3.2 map 3.2.1 map的介绍 3.2.2 ma ...

  9. C++ STL 关联式容器操作总结

    文章目录 set/multiset容器 set/multiset对象的构造 set/multiset的常规操作 set/multiset其他操作 map\multimap容器 map/multimap ...

  10. C++(STL):30 ---关联式容器map的operator[]和insert效率对比

    通过前面的学习我们知道,map 容器模板类中提供有 operator[ ] 和 insert() 这 2 个成员方法,而值得一提的是,这 2 个方法具有相同的功能,它们既可以实现向 map 容器中添加 ...

最新文章

  1. P1781 宇宙总统
  2. LINQ之路系列博客后记
  3. python- 基础 map方法
  4. Java EE与NoSQL的未来
  5. LeetCode 2040. 两个有序数组的第 K 小乘积(嵌套二分查找)
  6. Python中的特殊属性与方法
  7. python framework threads_python 多线程,进程的理解
  8. 白噪音和粉红噪音煲机_白噪音app体验报告
  9. 畅通工程(并查集模版题)
  10. Java:项目整体结构分析
  11. 遥感影像数据解译基本步骤
  12. Python查看图片模式及像素
  13. lumion材质系统室内渲染6.3
  14. 银河麒麟高级服务器v10 sp1 搭建局域网yum源(同步阿里yum源centos7.9)
  15. python中判断无向图是否有环_数据结构与算法:17 图
  16. Getx - 如何使用路由管理页面
  17. 生僻字_tte_linux_ttf_提取字体_打印生僻字_uni
  18. GO语言获取文件的大小
  19. 【ICCV2019 论文列表】出炉论文持续更新
  20. 艺赛旗(RPA) 【操作列表】

热门文章

  1. matlab 函数怎么写,MATLAB怎样定义函数(入门) 有一函数 f(x,y)=x^2+sinxy+2y , 写一程序, 输入自变量的值,输出函数值....
  2. 网狐棋牌游戏用户数据库QPAccountsDB开发文档
  3. 百度文库复制内容,留作笔记
  4. 切图直接导出html,Dreamweaver切图到生成网页的方法
  5. Spring Boot设置匹配指定后缀*.action *.do的路径
  6. 2020年对口升学计算机应用模拟题,2020年江西省对口计算机试卷
  7. Fortran: namelist
  8. MATLAB 2017 b 安装+下载+破解(win10,linux,mac)
  9. 算法设计与分析基础(第3版)
  10. c语言知识点总结大全(史上最全)