涉及:vector,pair

基本结构

map 从本质上来说是一颗二叉排序树,树上的节点类型为pair。pair类型中有两个重要的成员变量,其中 first 存储了 key ,second 存储了 value。

特性

map中的每一个键都是唯一的。即一个键只能对应一个值。

map中的值总是按序排列。

map中查找元素只能根据 key 来查找。

头文件

#include<map>

using namespace std;

声明与定义

map<[键类型],[值类型]> [变量名]; //默认按照 key 升序排列顺序存储

map<[键类型],[值类型],greater<值类型> > [变量名]; //支持定义了 '>' 运算符的类型,对 key 降序排列 // 注意后面两个尖括号之间要有空格

举例:

map<string,int> m;
map<MyType,string,greater<MyType> > m1; // MyType 是自己定义的类型,重载了 '>' 运算符

迭代器

begin() 返回指向第一个元素的迭代器

end() 返回指向最后一个元素之后的迭代器

map 变量的元素范围[ begin(), end() )

m.begin();
m.end();

注意:不能对迭代器做加法操作,例如 'm.begin() + 5' 是错误的。

容量

size() 返回map中元素的个数;

size();

添加元素

insert(pair<[键类型],[值类型]>([键对象],[值对象]));

insert(map<[键类型],[值类型]>::value_type([键对象],[值对象])); // 其实跟上面的赋值方法一模一样的。

还可以直接使用 '[]' 操作符。

m.insert( pair<MyType,string>(obj,"binbin") );
m.insert( map<MyType,string>::value_type(obj,"binbin") ); m[obj] = "binbin";

注意:如果重复插入 key 相同的键值对。那么对于 insert 方式,第一次插入以后的插入均无效;对于 '[]' 方式,每次插入都会将原来的键值对覆盖掉。

查找元素

count([键对象]) 判断键值对是否存在,有返回1,无返回0。

find([键对象]) 查找键对应的值,无论是否存在都返回元素指针(iterator对象)。当元素指针 等于 end() 的返回值时,表示键值对不存在。

// 方法一
if (m.count(keyObj)){ // 判断键值对是否存在,有返回1,无返回0
ValueType val = m[keyObj];
} // 方法二
map<KeyType,ValueType>::iterator i = m.find(keyObj); if(i != m.end())
ValueType val = i->second;

删除元素

clear() 清除所有元素

erase([元素指针]) 通过元素指针删除元素

erase([键对象]) 通过键删除元素

erase([起始元素],[结束元素]) 删除[起始元素,结束元素)范围内元素

m.clear();

m.erase(i);                       // i = m.begin() + 5;
m.erase(keyObj); //
m.erase(m.begin(),m.end()); //删除 map 中前5个元素

注意:不能对 'map<>::iterator' 对象 做加法操作,例如 'm.begin() + 5' 是错误的。

更改元素值

或者先删除原来的元素,再插入;或者找到元素后修改;或者用 [] 赋值。

仅列举后两种方法:

m["我是键"] = "我是值";

m.find("我是键")->second = "我是值"; // 上面 [] 方法的实质与本方法相同

排序

按 key 排序

map 中的元素是默认按照键排好序的,因此,只需要重载键类型的 < (或者 > )操作符即可。

struct St{
int a; bool operator < (const St & b){
return a < b;
}
bool operator > (const St & b){
return a > b;
}
} map<St,int> m1; // 按照St定义的 < 操作符对map元素进行排序
map<St,int,greater<St> > m2; // 按照St定义的 > 操作符对map元素进行排序

按 value 排序

把 map 中的元素都放入到 vector 中后再进行排序,map 中元素的类型为 pair。

参考的如下代码:

typedef pair<St,int> PAIR;              // 重定义

bool cmp(const PAIR &a,const PAIR &b){  // 比较函数
return a.second > b.second;
} vector<PAIR> vec(m1.begin(),m1.end()); // map 元素移交到 vector
sort(vec.begin(),vec.end(),cmp); // 排序

遍历

特别注意:遍历的结束条件中的比较运算符是 '!=' 而不是 '<'。

由于 map 元素类型是 pair,因此取出值的方式为 i->second。

for(map<int, int>::iterator i = m1.begin(); i != m1.end(); ++i){
cout << i->second << endl; }

代码示例

#include<map>
#include<vector> // 按值排序时用到
#include<iostream> // 输出用到 using namespace std; typedef pair<int, int> PAIR; struct ST{
int a; bool operator < (const ST &b){
return this->a < b.a;
}
}; bool cmp(const PAIR &a,const PAIR &b){
return a.second > b.second;
} int main(){
map<int, int> m1; m1[5] = 6;
m1[4] = 2;
m1[3] = 1; ////////////////////////////////////////////////////
// 删除元素 《《《《《 m1.erase(3); //输入 键对象
if (m1.count(3) == 0) {
cout << "键值对 3:1 被删除" << endl;
} m1.erase(m1.begin()); //输入 元素指针
cout << "删除当前第一个元素(4,2)后:"<< m1.begin()->second << endl; // 输出 6 m1.erase(m1.begin(),m1.end()); //输入 删除范围 if(m1.empty()) cout << "map 的元素都被删除了" << endl; cout << endl;
//////////////////////////////////////////////////// m1[5] = 6;
m1[4] = 9;
m1[3] = 1; ////////////////////////////////////////////////////
// 添加元素 《《《《《 m1.insert(PAIR(5,4)); cout << "insert方法重复添加键值对(5,4),结果 m1[5]:"<< m1[5] << endl; // 输出 6 m1[5] = 3; cout << "使用 [] 方式添加元素 m1[5]:"<< m1[5] << endl; // 输出 3 cout << endl; ////////////////////////////////////////////////////
// 修改元素 《《《《《 m1.find(4)->second = 2; // 原本 m1[5] = 9 cout << "修改元素 m1[4]:"<< m1[4] << endl; // 输出 2 cout << endl; ////////////////////////////////////////////////////
// 查找元素 《《《《《 // 当前的键值对情况
// m1[5] = 3;
// m1[4] = 2;
// m1[3] = 1; // 方法一
if (m1.count(4)){ // 判断键值对是否存在,存在则输出该值
cout << "找到元素 m1[4]:"<< m1[4] << endl;; //输出 2
} // 方法二
map<int,int>::iterator i = m1.find(5); if(i != m1.end())
cout << "找到元素 m1[5]:" << i->second << endl;; //输出 3 cout << endl;
////////////////////////////////////////////////////
// 遍历 《《《《《 // 当前的键值对情况
// m1[5] = 3;
// m1[4] = 2;
// m1[3] = 1; /// 输出 123
cout << "默认按 key 升序排列,遍历map:";
for(map<int, int>::iterator i = m1.begin(); i != m1.end(); ++i){ // 注意这里是用 != 标记结束的。
cout << i->second; } cout << endl;
cout << endl; ////////////////////////////////////////////////////
// 按值 value 排序 《《《《《 // 当前的键值对情况
// m1[5] = 3;
// m1[4] = 2;
// m1[3] = 1; vector<PAIR> vec(m1.begin(),m1.end());
sort(vec.begin(),vec.end(),cmp); // 按 value 降序排列 /// 输出 321 // 原本是按 key 升序排列,输出为 123
cout << "按 value 降序排序,遍历map:";
for (vector<PAIR>::iterator i = vec.begin();i < vec.end(); ++i) {
cout << i->second;
} cout << endl; }

output:

键值对 3:1 被删除
删除当前第一个元素(4,2)后:6
map 的元素都被删除了 insert方法重复添加键值对(5,4),结果 m1[5]:6
使用 [] 方式添加元素 m1[5]:3 修改元素 m1[4]:2 找到元素 m1[4]:2
找到元素 m1[5]:3 默认按 key 升序排列,遍历map:123 按 value 降序排序,遍历map:321

STL 中 map 的使用的更多相关文章

  1. C++ STL中Map的按Key排序和按Value排序

    map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...

  2. STL中map与hash_map的比较

    1. map : C++的STL中map是使用树来做查找算法; 时间复杂度:O(log2N) 2. hash_map : 使用hash表来排列配对,hash表是使用关键字来计算表位置; 时间复杂度:O ...

  3. STL中map与hash_map容器的选择收藏

    这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自al ...

  4. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

  5. C++中的STL中map用法详解(转)

    原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解   Map是STL的一个关联容器,它提供 ...

  6. C++ STL中Map的按Key排序跟按Value排序

    C++ STL中Map的按Key排序和按Value排序 map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定 ...

  7. stl中map的四种插入方法总结

    stl中map的四种插入方法总结方法一:pair例:map<int, string> mp;mp.insert(pair<int,string>(1,"aaaaa&q ...

  8. C++ STL 中 map 容器

    C++ STL 中 map 容器 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它 ...

  9. STL中map的使用

    知识点 C++中map提供的是一种键值对容器,里面的数据都是成对出现的.map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的. ...

  10. STL中map,set的基本用法示例

    本文主要是使用了STL中德map和set两个容器,使用了它们本身的一些功能函数(包括迭代器),介绍了它们的基本使用方式,是一个使用熟悉的过程. map的基本使用: #include "std ...

随机推荐

  1. <计算机系统结构中的8个伟大思想>

    摘自<计算机组成与设计>戴维帕森 ——面向摩尔定律的设计 ——使用抽象简化设计 ——加速大概率事件 ——通过并行提高性能 ——通过流水线提高性能 ——存储器层次 ——通过冗余提高可靠性

  2. Cordova搭建,所遇到问题处理

    环境:NodeJs.[Android SDK | IOS] 安装:npm install -g cordova 过程: 1.创建一个项目:cordova create myApp 2.选择平台: co ...

  3. C#扩展方法学习笔记

    C#扩展方法,简单的理解是不修改原来类的源代码的情况下,为某个类添加某个方法.扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的.它们的第一个参数指定该方法作用于哪个类型,并且该参数以 th ...

  4. php配置文件说明

    php-fpm.conf是PHP-FPM进程管理器的配置文件: php.ini是PHP解析器的配置文件: www.conf是php.ini的扩展文件

  5. springboot使用hibernate validator

    前言 在开发中经常需要写一些字段校验的代码,比如字段非空,字段长度限制,邮箱格式验证等等,写这些与业务逻辑关系不大的代码个人感觉有两个麻烦: 验证代码繁琐,重复劳动 方法内代码显得冗长 每次要看哪些参 ...

  6. win10搭建Python3环境

    到2019年初,Python3已经更新到了Python3.7.3,Python有两个大版本Python2和Python3,Python3是现在和未来的主流.         本文介绍Python3.7 ...

  7. VScode - 10个提高工作效率的快捷键

    复制行 shift + alt + up / down 移动行 alt + up / down 多选 按住alt + 鼠标单击 删除上个单词 ctrl + Backspace 全部保存 ctrl + ...

  8. Dynamics 365中的公告(Post)分析

    我是微软Dynamics 365 & Power Platform方面的工程师罗勇,也是2015年7月到2018年6月连续三年Dynamics CRM/Business Solutions方面 ...

  9. Jerome: Vulnhub Walkthrough

    nmap 扫描探测: ╰─ nmap -p1-65535 -sV -A -O -sT 10.10.202.135Starting Nmap 7.70 ( https://nmap.org ) at 2 ...

  10. 分组排序函数——row_number()

    1.MySQL8.0以上版本 用法1:无分组排序 Row_number() OVER(ORDER BY 字段 DESC)例如:Row_number() OVER(ORDER BY 学生成绩 DESC) ...