C++进阶 —— map

C++ MAP 详解 **Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会... 阅读详情

目录

一,map介绍

类pair

函数模板make_pair

二,map成员函数

三,map应用


一,map介绍

  • map是关联容器,按照特定的次序存储元素(由键key和值value组合而成的键值对);
    • 键key通常用于排序及唯一标识元素,而值value则存储与键key关联的内容;
    • 键key和值value的类型可能不同,且在map的内部,key与value通过成员类型value_type绑定在一起;
    • key是唯一的,并且不能修改;
    • map中的元素如用迭代器去遍历,可以得到一个有序序列;
typedef pair<const Key, T> value_type;
  • map中的元素始终根据其key按照其内部比较对象(compare)所指示的特定严格弱排序准则进行排序;
  • map中通过键值访问元素的速度通常比unordered_map容器慢,但map允许根据顺序对元素进行直接迭代;
  • map支持下标访问符,即在[ ]中放key,即可找到与key对应的value;
  • map通常被实现为二叉搜索树(红黑树),查找效率比较高O(logN);

类pair

template <class T1, class T2> struct pair;
  • 此类将一对值组合在一起,类型可以不同;
  • 可直接访问其公共成员变量first、second;
  • pair是tuple的特殊形式;

std::pair<int, double> p1(1, 2.5); //initialization (3) 初始化构造
std::pair<long, float> p2(p1);    //copy/move (2) 调用模板拷贝构造函数,会进行类型转换
std::pair<long, float> p3(std::move(p1)); //copy/move (2) 调用模板移动构造函数,会进行类型转换
std::pair<int, double> p4(p1);    //copy/move (2) 调用默认拷贝构造函数
std::pair<int, double> p5(std::move(p1)); //copy/move (2) 调用默认移动构造函数

函数模板make_pair

  • 构建一个pair对象,第一个元素为x,第二个元素为y;
  • 通过传递的参数可隐式的推导模板类型;
template <class T1, class T2>
  pair<V1,V2> make_pair (T1&& x, T2&& y);

//此函数返回,初始化构造一个pair对象,对参数进行完美转发
  pair<V1,V2>(std::forward<T1>(x),std::forward<T2>(y))
//自动推导类型,不需要显式指定类型
auto p1 = std::make_pair(1, "hello");        // pair<int, const char*>
auto p2 = std::make_pair(3.14, true);        // pair<double, bool>

//隐式转化 pair<double,char>
std::pair <int, int> bar;
bar = std::make_pair(10.5, 'A'); 

//完美转发
string str = "world";
auto p3 = std::make_pair(std::move(str), 42); // 移动语义,str 被转移

二,map成员函数

  • Key,键值对中key的类型;
  • T,键值对中value的类型;
  • Compare,比较器类型,map中的元素是按照key来比较的,默认按照小于来比较;
    • 一般情况下(内置类型)该参数不需传递;
    • 如无法比较(自定义类型),需要用户自己显示传递比较规则(一般情况下按照函数指针或仿函数来传递);

注:

  • map容器的元素是键值对(value_type),迭代器指向即为该元素的键值对;
  • value_type = pair<const key_type, mapped_type> 

构造函数

操作函数

//迭代器
      iterator begin() noexcept;
const_iterator begin() const noexcept;
      iterator end() noexcept;
const_iterator end() const noexcept;
      reverse_iterator rbegin() noexcept;
const_reverse_iterator rbegin() const noexcept;
      reverse_iterator rend() noexcept;
const_reverse_iterator rend() const noexcept;

//插入
single element (1)	
    pair<iterator,bool> insert (const value_type& val);
    template <class P> pair<iterator,bool> insert (P&& val);
with hint (2)	
    iterator insert (const_iterator position, const value_type& val);
    template <class P> iterator insert (const_iterator position, P&& val);
range (3)	
    template <class InputIterator>
    void insert (InputIterator first, InputIterator last);
initializer list (4)	
    void insert (initializer_list<value_type> il);

//删除
iterator  erase (const_iterator position);
size_type erase (const key_type& k);
iterator  erase (const_iterator first, const_iterator last);

//查找
      iterator find (const key_type& k);
const_iterator find (const key_type& k) const;

//访问
mapped_type& operator[] (const key_type& k);
mapped_type& operator[] (key_type&& k);

bool empty() const noexcept;
size_type size() const noexcept;
size_type count (const key_type& k) const;
void swap (map& x);
void clear() noexcept;
key_compare key_comp() const;
value_compare value_comp() const;

      iterator lower_bound (const key_type& k);
const_iterator lower_bound (const key_type& k) const;
      iterator upper_bound (const key_type& k);
const_iterator upper_bound (const key_type& k) const;

pair<const_iterator,const_iterator> equal_range (const key_type& k) const;
            pair<iterator,iterator> equal_range (const key_type& k);
int main()
{
	map<string, string> m;
	
	m.insert(pair<string, string>("peach", "桃子")); //pair<string, string> p("peach", "桃子");
	m.insert(make_pair("banan", "香蕉"));
	m["apple"] = "苹果";
	//m.at("waterme"); //不存在抛异常
	cout << m.size() << endl;
	cout << m.count("waterme") << endl;

	pair<map<string, string>::iterator, bool> ret = m.insert(make_pair("banan", "香蕉"));
	if (ret.second)
		cout << "insert successful" << endl;
	else
		cout << "insert failed" << endl;

	for (auto& e : m)
	{
		cout << e.first << "-->" << e.second << endl;
	}

	m.erase("apple");

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

	it = m.find("banan");
	cout << (*it).first << "-->" << (*it).second << endl;
	return 0;
}

三,map应用

// 字典和查找表(最常用)
std::map<std::string, std::string> countryCodes = {
    {"CN", "中国"},
    {"US", "美国"},
    {"JP", "日本"},
    {"UK", "英国"},
    {"FR", "法国"}
};

// 错误码映射
std::map<int, std::string> errorMessages = {
    {0, "成功"},
    {1, "文件未找到"},
    {2, "权限不足"},
    {3, "内存不足"},
    {4, "网络超时"}
};

std::string getCountryName(const std::string& code) {
    auto it = countryCodes.find(code);
    return it != countryCodes.end() ? it->second : "未知国家";
}

std::string getErrorMessage(int errorCode) {
    return errorMessages.count(errorCode) ? errorMessages[errorCode] : "未知错误";
}
// 统计单词频率
void wordFrequency(const std::vector<std::string>& words) {
    std::map<std::string, int> frequency;
    
    for (const auto& word : words) {
        frequency[word]++;
    }
    
    std::cout << "单词频率统计:" << std::endl;
    for (const auto& [word, count] : frequency) {
        std::cout << word << ": " << count << "次" << std::endl;
    }
}

// 投票统计
void voteCounter() {
    std::map<std::string, int> votes = {
        {"候选人A", 0},
        {"候选人B", 0},
        {"候选人C", 0}
    };
    
    // 模拟投票
    std::vector<std::string> voteResults = {"A", "B", "A", "C", "B", "A", "A"};
    
    for (const auto& vote : voteResults) {
        std::string candidate = "候选人" + vote;
        if (votes.find(candidate) != votes.end()) {
            votes[candidate]++;
        }
    }
    
    // 显示结果(自动按键排序)
    for (const auto& [candidate, count] : votes) {
        std::cout << candidate << ": " << count << "票" << std::endl;
    }
}

相关推荐

6.5 构网型储能系统的协同控制策略

本文系统阐述了构网型储能系统的协同控制策略,重点分析了多机组群协同运行面临的功率分配不均、动态响应失配等挑战。研究提出了改进型下垂控制与虚拟阻抗法、基于一致性算法的分布式协同控制等解决方案,探讨了构网型储能与同步发电机在惯性响应、一次调频等方面的协同机制,以及与跟网型电源在电压支撑、阻抗重塑等方面的互补作用。文章构建了分层控制架构,为实现多类型电源的全局优化运行提供了技术路径,对提升高比例新能源电力系统的稳定性具有重要意义。

技术工作者 999

c++中map详解

map简介 map是STL的一个关联容器,以键值对存储的数据,其类型可以自己定义,每个关键字在map中只能出现一次,关键字不能修改,值可以修改;map同set、multiset、multimap(与map的差别仅在于multimap允许一个键对应多个值)内部数据结构都是红黑树,而java中的hashmap是以hash table实现的。所以map内部有序(自动排序),查找时间复杂度为O(logn)。 map用法 1、头文件 #include<map> 2、 ...

weixin_41501074的博客 9万+

ADS2020与SystemVue2020Update1.0同机安装避坑指南:解决License冲突,实现EVM联合仿真

本文详细介绍了ADS2020与SystemVue2020 Update1.0同机安装的完整解决方案,重点解决License冲突问题,实现EVM联合仿真。通过合理的安装顺序、路径规划和License服务配置,确保两款EDA工具和谐共存,为射频与微波电路设计提供高效仿真环境。

weixin_30271335的博客 347

C++中的map用法详解

对于C++中的map容器的用法详解,简单易懂,非常适合小白同学

gaoqiandr的博客 5万+

Cocos Creator实战:5步搞定棋牌游戏大厅场景开发(附完整代码)

本文详细介绍了使用Cocos Creator 3.8开发棋牌游戏大厅的5个关键步骤,包括工程配置、动态UI系统实现、核心交互功能开发、性能优化及调试发布技巧。通过模块化代码和实战案例,帮助开发者快速构建高交互性的棋牌游戏大厅,提升用户留存率。

weixin_29002209的博客 353

MIPI CSI-2数据加扰技术解析:LFSR实现与多通道同步策略

本文深入解析了MIPI CSI-2协议中的数据加扰技术,该技术通过线性反馈移位寄存器(LFSR)对图像数据进行随机化处理,旨在有效降低高速传输中的电磁干扰。文章详细阐述了LFSR的工作原理、D-PHY与C-PHY物理层不同的初始化与同步策略,并探讨了多通道同步的实现方法,为高速接口的EMC设计与调试提供了实践指导。

weixin_29207149的博客 383

【C++】手把手教你看懂的 STL map 详解(超详细解析,小白一看就懂!!)

【map】是STL中的容器之一,不同于普通容器,它的查找速度极快,常用来存储各种经常被检索的数据,因为容器的底层是【红黑树】。除此之外,还可以借助其特殊的性质,解决部分难题。

weixin_45031801的博客 9226

STM32H750VB与AD5292通讯,写入阻值后,AD5292 的阻值没有变化,如何解决?

🏆 本文收录于《全栈Bug调优(实战版)》专栏,致力于分享我在项目实战过程中遇到的各类Bug及其原因,并提供切实有效的解决方案。无论你是初学者还是经验丰富的开发者,本文将为你指引出一条更高效的Bug修复之路,助你早日登顶,迈向财富自由的梦想🚀!同时,欢迎大家关注、收藏、订阅本专栏,更多精彩内容正在持续更新中。让我们一起进步,Up!Up!Up!    备注: 部分问题/难题源自互联网,经过精心筛选和整理,结合数位十多年大厂实战经验资深大佬经验总结所得,数条可行方案供所需之人参考。

**My Coding Family** 1097

详解c++---map的介绍

map的用法介绍

qq_68695298的博客 9010

超级全的PCB LAYOUT高速信号走线指南——简化应用版

在PCB Layout中,几乎涵盖了所有的高速信号走线指南。包括了TF/SD、HDMI、LVDS、DVP、eDP、MIPI、USB2.0、USB3.0、MAC、BT.1120、PCIE高速信号等等。此版本为简化版。

bhxc809751502的博客 8546

uniapp:人脸识别功能,已测试,直接复制源码,支持H5,APP安卓。不依赖任何js,SDK。

uniapp人脸识别功能,已测试可直接复制源码,支持H5,APP安卓。不依赖任何js,SDK。 APP效果图:

sunluyi的博客 2225

Cpp進階:Map 映射表

Cpp 進階:Map 映射表 文章目錄Cpp 進階:Map 映射表簡介參考正文重要類型元素操作`map.insert` 插入(增)`map.find`、`map.lower_bound`、`map.upper_bound` 查找(查)`map.erase`、`map.clear` 刪除元素(刪)迭代器其他方法結語 簡介 上一篇:Cpp 進階:Vector 向量介紹了 C++ 的 STL 中 Vector 容器的使用方式。最基礎的數據結構中最常用的除了序列(sequence)就當數映射表(map)了(如 JS

超悠閒的博客 551

[Python人工智能] 三十六.基于Transformer的商品评论情感分析 (2)keras构建多头自注意力(Transformer)模型

本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前一篇文章利用Keras构建深度学习模型并实现了情感分析。这篇文章将介绍Transformer基础知识,并通过Keras构建多头自注意力(Transformer)模型,实现IMDB电影影评数据情感分析。基础性文章,希望对您有所帮助!...

杨秀璋的专栏 4908

C++进阶-map

本文介绍了C++ STL中的map容器。map是基于二叉搜索树实现的键值对容器,具有自动排序特性。文章详细讲解了map的声明方式、构造函数、operator[]操作符(可查找/插入元素)、at方法(安全访问)、emplace_hint高效插入等核心功能。特别强调了map与set的区别在于存储键值对,以及operator[]的独特行为(找不到键时会自动插入)。还介绍了辅助类pair的用法,以及key_comp/value_comp比较函数的使用。通过多个代码示例演示了map的基本操作,包括元素访问、修改和异常

博客是在C++/Java/Liunx/算法的学习阶段所写的博客,内容可能不是很全面 992

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++进阶 map和set

简单介绍C++中map和set容器

小萌新的博客 954

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

【C++进阶】封装红黑树实现map和set

【C++进阶】封装红黑树实现map和set

2301_78022459的博客 1041

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

c++进阶--unordered_set和unordered_map的使用

3. unordered_set和set的第⼆个差异是迭代器的差异,set的iterator是双向迭代器,unordered_set是单向迭代器,其次set底层是红⿊树,红⿊树是⼆叉搜索树,⾛中序遍历是有序的,所以set迭代器遍历是有序+去重。4. unordered_set和set的第三个差异是性能的差异,整体⽽⾔⼤多数场景下,unordered_set的增删查改更快⼀些,因为红⿊树增删查改效率是 ,⽽哈希表增删查平均效率是 ,具体可以参看下⾯代码的演⽰的对⽐差异。

2302_79606537的博客 1078

【C++进阶】第5课—map容器

map的声明如下,Key就是map底层关键字的类型,T是map底层value的类型,set默认要求Key支持小于比较,如果不支持或者需要的话可以自行实现仿函数传给第二个模版参数,map底层存储数据的内存是从空间配置器申请的。⼀般情况下,我们都不需要传后两个模版参数。map底层是用红黑树实现,增删查改效率是O(logN),迭代器遍历是走的中序,所以是按key有序顺序遍历的map里的key/value也被称为键值对,一个key匹配一个value,且key必须是唯一的。

weixin_70620792的博客 701

C++进阶-map的应用

本文系统介绍了C++中map容器的扩展知识和应用实践。首先补充了map的多种插入方式、键值访问方法及operator[]的行为特性。然后通过力扣两道典型题目进行实战演练:在前K个高频词问题中,比较了基于map/multimap、stable_sort和自定义排序三种解法;在随机链表复制问题中,对比了C语言传统解法和利用map存储节点映射关系的C++优化解法。文章还简要提及了map的其他成员函数如find、count等,并预告后续将深入讲解AVL树等高级数据结构。全文通过代码示例详细展示了map在实际问题中的

博客是在C++/Java/Liunx/算法的学习阶段所写的博客,内容可能不是很全面 936

C++进阶之map与set

stl中将数据结构叫做容器。 容器分为 序列式容器:vector/list... 就类似线性表 关联史容器:map/set.. 数据之间有强烈的关联性,底层是搜索树 栈和队列是适配器 set底层就是搜索树。 void test_set1() { //排序+去重 set<int> s; s.insert(3); s.insert(1); s.insert(8); s.insert(2); s.insert(5); s.insert(5); s.insert(5)

cls的博客 3076

C++进阶——set和map

set和map,看看吧看看吧看看吧看看吧反正又不吃亏....................

2301_79830926的博客 1136

C++进阶—map和set

set文档介绍set是按照一定次序存储元素的容器在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。set在底层是用二叉搜索树(红黑树)实现的。

Awkwardx的博客 676

C++进阶之map和set

先来看看set的文档说明:set是按照一定次序存储元素的容器在set中,元素的value也标识它(value就是key,类型为T),并且每个value必须是唯一的。set中的元素不能在容器中修改(元素总是const),但是可以从容器中插入或删除它们。在内部,set中的元素总是按照其内部比较对象(类型比较)所指示的特定严格弱排序准则进行排序。set容器通过key访问单个元素的速度通常比unordered_set容器慢,但它们允许根据顺序对子集进行直接迭代。

JYXCZYH的博客 808

【C++进阶】map和set

在C++ STL中,容器分为两大类: 序列式容器:vector、list、deque、forward_list等,底层为线性序列结构,存储元素本身 关联式容器:map、set、multimap、multiset等,存储键值对,数据检索效率更高

x_2023_713的博客 1054

【C++进阶】map和set的使用

【C++进阶】map和set的使用

2301_78022459的博客 1498

C++进阶——map和set的使用

1. set的声明如下,T就是set底层关键字key的类型。2.set默认要求key支持小于比较(升序),如果不支持或者想按自己的需求走可以自行实现仿函数传给第二个模版参数。3. set底层存储数据的内存是从空间配置器申请的,如果需要可以自己实现内存池,传给第三个参 数。4. 一般情况下,我们都不需要传后两个模版参数。5.set底层是用红黑树实现,增删查效率是O(logN)。迭代器遍历走的是搜索树的中序,所以是有序。

博客 | 复习知识点 + 练习 + 最终的领悟 | 全力以赴 1284
上一篇: C++进阶 —— set
下一篇: C++进阶 —— multimap
挨代码
博客等级 码龄5年 1696粉丝 384原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值