四、STL容器:map

2023-11-10

4 map

4.1 简介

mapkey-value构成的集合。

4.2 操作

map是键值对<key,value>构据集合。key必须唯一

  • 主要用来查找key对应value,要求key必须是可排序的,必须支持<比较运算符。
  • map默认是以key升序存放键值对<key,value>数据,比较适合二分查找。

map内部结构:
1、map使用pair<key,value>类模板保存keyvalue
2、pair<key,value>有两个public成员变量:firstsecondfirst存放key,second存放value
3、在map里面可以使用map<>::value_type表示pair<key,value>

typedef pair<key,value> value_type;

4.2.1 初始化

1、默认构造(可带参数)
2、复制构造
3、范围赋值构造

初始化时必须给map<>类模板同时设置keyvalue的类型模板实参。
实参类型不限于基本类型、类类型(class、struct、union),还可以是容器模板。

4.2.2 基本操作

  • 迭代器
迭代器 作用
c.begin() 头迭代器
c.end() 尾迭代器
c.rbegin() 反向头迭代器
c.rend() 反向尾迭代器

注:与vector相似。

  • 数据量操作
函数 作用
c.size() 大小
c.max_size() 最大大小
c.empty() 判空
c.clear() 清空

4.2.3 添加数据

1、insert插入pair<>数据

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
    cout << val.first <<" " << val.second << endl;
}
int main(){
    map<int,int> m;
    for(int i=0;i<10;i++){
        m.insert(pair<int,int>(i,i*10));
    }
    for_each(m.begin(),m.end(),Display);
}
0 0
1 10
2 20
3 30
4 40
5 50
6 60
7 70
8 80
9 90

2、insert插入map<>::value_type数据

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
    cout << val.first <<" " << val.second << endl;
}
int main(){
    map<int,int> m;
    for(int i=0;i<10;i++){
        m.insert(map<int,int>::value_type(i,i*10));
    }
    for_each(m.begin(),m.end(),Display);
}
0 0
1 10
2 20
3 30
4 40
5 50
6 60
7 70
8 80
9 90

3、insert插入make_pair数据

make_pair是一个函数模板,类似与如下实现:

template<class K,class V)
inline pair<K,V> make_pair(K const& k,V const& v){
    return pair<K,V>(k,v);
}
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
    cout << val.first <<" " << val.second << endl;
}
int main(){
    map<int,int> m;
    for(int i=0;i<10;i++){
        m.insert(make_pair(i,i*10));
    }

    for_each(m.begin(),m.end(),Display);
}

4、下标运算符[]添加数据

#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
    cout << val.first <<" " << val.second << endl;
}
int main(){
    map<int,int> m;
    for(int i=0;i<10;i++){
        m[i] = i*10;
    }
    for_each(m.begin(),m.end(),Display);
}

注:map只有在访问key,如果key不存在则会创建,反之,使用已存在的<key,val>。对于已存在的keyinsert()操作是无法插入数据,可以通过判断insert()的返回值pair<map<>::iterator,bool>,得知是否插入成功。

4.2.4 遍历

1、迭代器for循环

for(map<int,int>::iterator it = m.begin();it != m.end();it++){
        cout << "[" << it->first << "]=" << it->second() << endl; 
}

2、for_each()循环

定义函数指针

inline void Display(map<int,int>::value_type const& val){
    cout << "[" << val.first << "]=" << val.second << endl;
}

执行for_each

for_each(m.begin(),m.end(),Display);

3、C++11auto迭代器写法

for(auto it = m.begin();it != m.end();it++){
        cout << "[" << it->first << "]=" << it->second() << endl; 
}

4、C++11 for-loop-scope迭代器写法

for(auto p : m){
    cout << "[" << p.first << "]=" << p.second << endl;
}

5、C++11 for_each()lamdba表达式

for_each(m.begin(),m.end(),[](map<int,int>::value_type& p){
    cout << "[" << p.first << "]=" << p.second << endl;
});

4.2.5 key查找

1、count()判断key是否存在

if(m.count(key) == 1){
     ...
}

2、find()判断key是否存在以及位置

map<int,int>::iterator it = m.find(key);
if(m.end() != it){
     ...
}

3、下标运算符[]

m[key];

如果key不存在,默认创建。

4.2.6 区域查找

成员变量 作用
m.lower_bound(key) key下边界
m.upper_bound(key) key上边界
m.equal_range(key) key上下边界

4.2.7 删除

1、关键字删除

m.erase(key);

2、迭代器删除

m.erase(m.begin());

3、区域删除

m.erase(it_a,it_b);

4.2.8 排序

默认按照key升序排列。自定义排序是,可以在实例化加上keycomp仿函数,重载<运算符

map<key类型,value类型,comp> m;

4.3 实例

1、两个数组合并成一个map

#include <iostream>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;
void Display(map<int,int>::value_type const& val){
    cout << "[" << val.first << "]=" << val.second << endl;
}
class MapMaker{
public:
    MapMaker(map<int,int>& m):m_(m){}
    inline bool operator()(int k,int v){
        return m_.insert(make_pair(k,v)).second;
    }
private:
    map<int,int>& m_;
};
int main(){
    map<int,int> m;
    int arr1[] = {1,2,1,4,5,2,3,4}; 
    int arr2[] = {19,29,39,49,59,69,79,89}; 
    bool res[8];
    transform(arr1,arr1+8,arr2,res,MapMaker(m));
    cout<< boolalpha;
    copy(res,res+8,ostream_iterator<bool>(cout,","));
    cout<< noboolalpha << endl;
    for_each(m.begin(),m.end(),Display);
}
true,true,false,true,true,false,true,false,
[1]=19
[2]=29
[3]=79
[4]=49
[5]=59

注:在C++11中transform可以使用lamdba表达式,改写成

transform(arr1,arr1+8,arr2,res,[&m](int k,int v){
    return m.insert(make_pair(k,v)).second;
});

2、把map的key和value各自分解成一个vector

#include <iostream>
#include <algorithm>
#include <iterator> // ostream_iterator
#include <vector>
#include <map>
using namespace std;
// 仿函数
class Spliter{
public:
    Spliter(vector<int>& k,vector<int>& v):k_(k),v_(v){}
    void operator()(map<int,int>::value_type const& pair){
        k_.push_back(pair.first);
        v_.push_back(pair.second);
    }
private:
    vector<int>& k_;
    vector<int>& v_;
};
int main () {
  map<int,int> m;
  for(int i=0;i<10;i++){
    m[i] = i*10;
  }
  vector<int> keys;
  vector<int> values;
  for_each(m.begin(),m.end(),Spliter(keys,values));
  copy(keys.begin(),keys.end(),ostream_iterator<int>(cout,","));
  cout << endl;
  copy(values.begin(),values.end(),ostream_iterator<int>(cout,","));
  cout << endl;
  return 0;
}
0,1,2,3,4,5,6,7,8,9,
0,10,20,30,40,50,60,70,80,90,

在C++11中for_each可以使用lamdba表达式,改写成

for_each(m.begin(),m.end(),[&keys,&values](map<int,int>::value_type const& pair){
        keys.push_back(pair.first);
        values.push_back(pair.second);
});

使用C++11 for-loop-scope语法

for(auto p:m){
    keys.push_back(p.first);
    values.push_back(p.second);
}

3、map实现采用映射实现字典查找

#include <iostream>
#include <map>

using namespace std;

int main(){
    // map映射 dict 目录/字典
    map<string,string> dict = {
    	//key    value
	{"Apple","苹果"},
    	{"Orange","橘子"},
    	{"Banana","香蕉"},
	{"苹果","Apple"},
    	{"橘子","Orange"},
    	{"香蕉","Banana"},
    	{"Orange","橘子"}, //重复key忽略
    };

    dict["Car"] = "汽车"; //添加数据
    dict.insert(pair<string,string>("汽车","Car"));
    dict.insert(make_pair("Cat","猫"));
    dict.insert({"猫","Cat"}); //C++11
    dict["Car"] = "小汽车"; //修改数据

    map<string,string>::iterator it = dict.begin();
    while(it != dict.end()){
    	//pair<string,string>  first,second
	cout << it->first << " " << it->second << endl;
    	it++;
    }

    string s;
    cin >> s; 
    //if(dict.count(s) == 1){
    if(dict.find(s) != dict.end()){
    	cout << dict[s] << endl;
    }else{
    	cout << "不存在" << endl;
    }
}
Apple 苹果
Banana 香蕉
Car 小汽车
Cat 猫
Orange 橘子
橘子 Orange
汽车 Car
猫 Cat
苹果 Apple
香蕉 Banana
猫 
Cat
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

四、STL容器:map 的相关文章

随机推荐

  • 特征缩放(归一化处理)

    在我们面对多维特征问题的时候 我们要保证这些特征都具有相近的尺度 这将帮助梯度下降算法更快地收敛 以房价问题为例 假设我们使用两个特征 房屋的尺寸和房间的数量 尺寸的值为 0 2000平方英尺 而房间数量的值则是0 5 以两个参数分别为横纵
  • 带有 OpenCV.js 的 ESP32-CAM Web 服务器:颜色识别和跟踪

    本教程介绍了使用 ESP32 摄像头网络服务器环境的 OpenCV js 和 OpenCV 工具 例如 我们将构建一个简单的 ESP32 摄像头网络服务器 其中包括对移动物体的颜色检测和跟踪 本教程绝不是对 OpenCV 可以提供给 ESP
  • 学乐高机器人还是学习少儿编程

    学乐高机器人还是学习少儿编程 对于很多的家长来说 孩子的学习一直都是他们非常关心和重视的一件事情 很多的家长在给孩子选择学习课程的时候 也是非常的耐心的 他们会给孩子选择一些能够有利于孩子成长的课程 就拿现在很多的家长想要孩子去学习机器人编
  • 生成树协议实验报告_“网络工程师培训”基础教程:OSPF协议及配置

    OSPF协议概述 OSPF 是 Open Shortest Path First 即 开放最短路由优先协议 的缩写 它是 IETF 组织开发的一个基于链路状态的自治系统内部路由协议 在IP 网络上 它通过收集和传递自治系统的链路状态来动态地
  • 牛客网Verilog刷题——VL54

    牛客网Verilog刷题 VL54 题目 答案 题目 实现一个深度为8 位宽为4bit的双端口RAM 数据全部初始化为0000 具有两组端口 分别用于读数据和写数据 读写操作可以同时进行 当读数据指示信号read en有效时 通过读地址信号
  • ffmpeg命令行map参数的使用

    介绍 理解 map参数的最好办法就是想像一下怎么去告诉ffmpeg你要从源文件中选择 拷贝哪个流到输出文件 输出文件的stream顺序取决于在命令行中 map的参数顺序 下面有一些例子 默认 默认操作 没有指定map参数 比如 ffmpeg
  • IR2104电机驱动

    目录 一 IR2104的引脚定义 二 IR2104的内部原理 三 半桥驱动原理分析 四 全桥驱动原理分析 五 电感电流回流路径的建立 六 自举电容容值的计算与自举二极管选型 七 mos管发热可能的问题 八 推荐阅读 一 IR2104的引脚定
  • R语言中如何进行PCA分析?利用ggplot和prcomp绘制基因表达量分析图

    学习笔记的主要内容是在R语言中利用ggplot2进行PCA分析和绘图 包括简单分析与操作流程 对比不同方式得到的结果差异 提供脚本代码供练习 PCA分析的原理 在处理基因差异表达数据时 有时候需要分析其中因素的影响最大 判断结果的关系 这个
  • InstructGPT:彻底改变人工智能驱动的语言模型

    目录 什么是InstructGPT 人工智能驱动的语言模型的演变 InstructGPT 模型与 GPT 3 相比如何 通过 OpenAI API 访问 InstructGPT 1 访问platform openai com并创建或登录您的
  • Linux中select poll和epoll的区别

    原文地址 http www cnblogs com bigwangdi p 3182958 html 在Linux Socket服务器短编程时 为了处理大量客户的连接请求 需要使用非阻塞I O和复用 select poll和epoll是Li
  • Node.js Modules 模块

    模块 https nodejs org docs v9 2 0 api modules html Node js has a simple module loading system In Node js files and modules
  • 美国移动网络运营商:是时候关闭 3G 了

    整理 祝涛 出品 CSDN ID CSDNnews 你的手机现在正使用什么样的网络服务呢 是4G还是5G呢 如果美国地区的用户依然停留在3G 他们可能需要在手机服务提供商关闭3G网络之前升级 以避免失去服务 美国联邦通信委员会 Federa
  • 华为OD机试 -扑克牌大小(C++ & Java & JS & Python)

    描述 扑克牌游戏大家应该都比较熟悉了 一副牌由54张组成 含3 A 2各4张 小王1张 大王1张 牌面从小到大用如下字符和字符串表示 其中 小写joker表示小王 大写JOKER表示大王 3 4 5 6 7 8 9 10 J Q K A 2
  • 联想Y9000X Opencore引导黑苹果Catalina10.15.6安装教程

    Y9000X 2020黑苹果安装教程 非商业用途 仅用于自己记录学习研究 Y9000X Opencore 安装双硬盘双系统教程 电脑配置 前期准备 安装流程 1 写入U盘镜像 2 更换EFI文件 3 磁盘分区 4 系统安装 5 将U盘中的E
  • [c++]opencv 鼠标响应函数传入外部参数(图像)问题

    参考博客 https blog csdn net my lord article details 53927865 https blog csdn net aiyueyueaoe article details 118192972 http
  • C语言开发MicroPython模块(添加module)

    MicroPython添加模块框架模式相对简单 只需要按照定义好的固定框架就可以添加模块 module 一 向固件里面添加module 1 1 编写mymodule c文件 在ports esp32文件夹下新建一个文件mymodule c
  • 域/AD域

    域 定义 域模型是针对大型网络的管理需求设计的 域就是共享用户账号 计算机账号和安全策略的计算机集合 组成 域网络的组成 一般情况下 有三种计算机 域控制器 上存储着Active Directoy 成员服务器 负责提供邮件 数据库 DHCP
  • Flink学习22:窗口的划分

    1 简介 主要有2种窗口 一个基于时间窗口 一个是基于数量窗口 时间窗口中起止时间是 左闭右开 2 时间概念 2 1 事件生成时间 EventTime 指的是数据在设备上产生的时间 这种模式下 不管数据何时到达或者顺序如何 都能得到一致的结
  • 从设备树(dtb格式数据)中解析出bootargs

    1 函数调用关系 start kernel setup arch setup machine fdt early init dt scan nodes 遍历设备树的节点 解析出重要的信息用于内核启动 of scan flat dt 解析设备
  • 四、STL容器:map

    4 map 4 1 简介 map是key value构成的集合 4 2 操作 map是键值对