C++ map用法详细总结40例

文章目录

      • 1. 定义与初始化
      • 2. 插入元素
      • 3. 查找元素
      • 4. 删除元素
      • 5. 遍历
      • 6. 访问成员函数
      • 7. 修改元素
      • 8. 注意事项
      • 9. 使用 `equal_range` 查找键值范围
      • 10. 使用 `emplace` 添加元素
      • 11. 使用 `cbegin` 和 `cend` 获取常量迭代器
      • 12. 排序规则自定义
      • 13. 使用 `multimap` 存储重复键
      • 14. 判断 map 是否包含某个键
      • 15. 访问 map 的第一个和最后一个元素
      • 16. 使用 `emplace_hint` 插入元素
      • 17. 使用 `extract` 移除并返回元素
      • 18. 使用 `merge` 合并两个 map
      • 19. 使用 `extract` 和 `insert` 实现元素移动
      • 20. 使用 `swap` 函数交换两个 map 的内容
      • 21. 使用 `lower_bound` 和 `upper_bound` 实现范围查找
      • 22. 使用 `emplace_hint` 并结合 `find` 获取更好的插入性能
      • 23. 使用 `key_comp` 和 `value_comp` 比较器
      • 24. 使用 `equal_range` 进行精确查找
      • 25. 使用 `max_size` 查询最大容量
      • 26. 使用 `reserve` 预留空间
      • 27. 使用 `extract` 与 `emplace` 实现原子化的更新操作
      • 28. 使用 `extract` 移除元素并转换为普通对象
      • 29. 使用 `extract` 清空 map
      • 30. 使用 `std::transform` 迭代 map 并应用函数
      • 31. 使用 `std::copy` 将 map 转换为 vector
      • 32. 使用 `std::all_of`, `std::any_of`, `std::none_of` 对 map 进行条件检查
      • 33. 使用 `std::accumulate` 计算 map 中所有值的总和
      • 34. 使用 `std::for_each` 对 map 进行遍历并打印
      • 35. 使用 `std::map::extract` 结合 `std::set` 移除特定键集合中的元素
      • 36. 使用 `std::map::emplace_hint` 更新已存在的键值对
      • 37. 使用 `std::unordered_map` 改善查找性能(散列映射)
      • 38. 使用 `std::map::key_type` 和 `mapped_type` 获取键和值的类型
      • 39. 使用 `std::advance` 移动迭代器
      • 40. 使用 `std::prev` 和 `std::next` 访问相邻元素

C++ map用法详细总结

C++ 中的 std::map 是标准库中的一种关联容器,它提供了一种键值对的存储方式,其中键是唯一的,并且按照升序排序。以下是对 std::map 的详细用法总结:

1. 定义与初始化

#include <map>
using namespace std;// 声明一个 map,键为 string 类型,值为 int 类型
map<string, int> myMap;// 直接初始化
map<string, int> myMap2 = {{"Alice", 85},{"Bob", 90},{"Charlie", 95}
};

2. 插入元素

// 插入单个键值对
myMap["David"] = 88;// 使用 insert 方法插入
pair<map<string, int>::iterator, bool> result = myMap.insert({"Eve", 92});

3. 查找元素

// 查找键
auto it = myMap.find("Alice");
if (it != myMap.end()) {cout << "Alice's grade: " << it->second << endl;
} else {cout << "Alice not found." << endl;
}// 使用 at() 获取值,若键不存在则抛出异常
try {cout << "Charlie's grade: " << myMap.at("Charlie") << endl;
} catch (const out_of_range&) {cout << "Charlie not found." << endl;
}

4. 删除元素

// 删除指定键的元素
myMap.erase("Alice");// 删除迭代器指向的元素
auto it2 = myMap.find("Bob");
if (it2 != myMap.end()) {myMap.erase(it2);
}

5. 遍历

// 使用迭代器遍历
for (auto it = myMap.begin(); it != myMap.end(); ++it) {cout << it->first << ": " << it->second << endl;
}// 使用范围for循环遍历
for (const auto& entry : myMap) {cout << entry.first << ": " << entry.second << endl;
}

6. 访问成员函数

  • size():返回 map 中元素的数量。
  • empty():如果 map 为空则返回 true,否则返回 false
  • clear():清空 map 内的所有元素。
  • count(key):返回 key 出现的次数(对于 map 总是 0 或 1,因为键是唯一的)。
  • lower_bound(key)upper_bound(key):返回指向首个大于等于(小于)key的元素的迭代器。

7. 修改元素

// 更新已有键的值
myMap["David"] = 90;

8. 注意事项

  • map 中的键值对是根据键的升序排列的。
  • map 的键是不可变的,一旦插入就不能更改键的值。
  • map 的迭代器在删除元素时可能会失效,除非你使用的是 erase() 返回的新迭代器。

以上总结了C++中 std::map 关键用法,实际使用时应根据具体需求选择合适的方法操作。

9. 使用 equal_range 查找键值范围

equal_range 函数返回一个迭代器对,该对包含 map 中与给定键相等的所有元素的范围(对于 map,始终只有一个元素)。这对于在已排序的键值对中查找键值范围特别有用。

auto range = myMap.equal_range("Bob");for (auto it = range.first; it != range.second; ++it) {cout << it->first << ": " << it->second << endl;
}

10. 使用 emplace 添加元素

emplace 函数可以在 map 中直接构造(而不是拷贝或移动)元素,从而节省时间和空间。它接受与 map 键值对类型相同的参数。

myMap.emplace("Frank", 93); // 直接在map中构造新的键值对

11. 使用 cbegincend 获取常量迭代器

当你需要在不影响 map 的情况下遍历其元素时,可以使用 cbegin()cend() 获取常量迭代器。

for (const auto& entry : myMap) {// 使用常量引用,不会修改 map 中的元素
}// 或者使用常量迭代器
for (auto it = myMap.cbegin(); it != myMap.cend(); ++it) {// ...
}

12. 排序规则自定义

默认情况下,std::map 的键按照 < 运算符进行排序。如果要使用其他比较函数,可以提供一个自定义的比较器。

struct CustomComparator {bool operator()(const std::string& a, const std::string& b) const {return a.length() < b.length(); // 按字符串长度排序}
};std::map<std::string, int, CustomComparator> myCustomMap;

13. 使用 multimap 存储重复键

std::multimap 类似于 std::map,但允许有重复的键,每个键可以关联多个值。

总之,C++ std::map 提供了丰富的功能,支持高效的键值对存储和检索,尤其适合那些需要根据键排序并保持唯一性的场景。通过熟练掌握上述用法,你可以更好地利用这一强大工具。

14. 判断 map 是否包含某个键

除了使用 find 函数检查键是否存在之外,也可以直接使用 count 函数。count 函数返回键在 map 中出现的次数,对于 map 来说,如果键存在则返回1,否则返回0。

if (myMap.count("Alice") > 0) {cout << "Alice is in the map." << endl;
} else {cout << "Alice is not in the map." << endl;
}

15. 访问 map 的第一个和最后一个元素

  • begin() 返回指向 map 中第一个元素(按键值排序)的迭代器。
  • end() 返回指向 map 结束点的迭代器,不指向任何元素。
  • rbegin()rend() 分别返回逆向迭代器,指向 map 中最后一个元素(按键值排序)和逆向迭代器的结束点。
// 输出 map 中的第一个元素
if (!myMap.empty()) {std::cout << "First element: " << myMap.begin()->first << ": " << myMap.begin()->second << std::endl;
}// 输出 map 中的最后一个元素
if (!myMap.empty()) {std::cout << "Last element: " << myMap.rbegin()->first << ": " << myMap.rbegin()->second << std::endl;
}

16. 使用 emplace_hint 插入元素

emplace_hint 函数类似于 emplace,但在已经知道插入点的情况下,可以提供一个迭代器提示,有可能提高插入效率。

auto hint = myMap.lower_bound("David"); // 获取可能的插入点
myMap.emplace_hint(hint, "Eve", 91); // 在 "David" 之后或相应位置插入新的键值对

17. 使用 extract 移除并返回元素

C++17 引入了 extract 函数,可以从容器中移除元素并返回一个包含该元素的 std::pair,其中 .first 是指向元素的迭代器,.second 是一个包含了原容器中元素的 std::optional

if (auto result = myMap.extract("Alice"); result.second) {std::cout << "Removed Alice with grade: " << result.first->second << std::endl;// 可以将移除的元素插入到另一个 map 中anotherMap.insert(std::move(result.first));
}

通过熟悉这些高级用法和功能,开发者可以更加灵活高效地使用 C++ 的 std::map 容器。

18. 使用 merge 合并两个 map

C++17 中引入了 merge 函数,可以将一个 map 的内容合并到另一个 map 中,合并过程中如果遇到相同键值,后者会替换前者。

std::map<std::string, int> map1 = {{"Alice", 85}, {"Bob", 90}};
std::map<std::string, int> map2 = {{"Bob", 92}, {"Charlie", 95}};map1.merge(map2); // 合并后,map1 中 Bob 的成绩变为 92// map1: {"Alice": 85, "Bob": 92, "Charlie": 95}
// map2: {}

19. 使用 extractinsert 实现元素移动

extract 函数可以配合 insert 函数实现元素在 map 间的移动,而不仅仅是复制。

std::map<std::string, int> map1, map2;// ... 填充 map1 和 map2 ...// 将 map1 中的 "Alice" 移动到 map2
if (auto it = map1.extract("Alice"); it.second) {map2.insert(std::move(it.mapped()));
}// 此时 map1 不再包含 "Alice"

20. 使用 swap 函数交换两个 map 的内容

swap 函数可以交换两个 map 的所有内容,包括内部的键值对及其顺序。

std::map<std::string, int> map1 = {{"Alice", 85}, {"Bob", 90}};
std::map<std::string, int> map2 = {{"Charlie", 95}, {"David", 98}};std::swap(map1, map2);// 交换后,map1 和 map2 的内容互换

通过学习和实践以上 std::map 的各种用法,开发者能够更好地应对不同场景下的键值对存储和查询需求,编写出高效且易于维护的代码。

当然,以下是更多的 std::map 使用示例:

21. 使用 lower_boundupper_bound 实现范围查找

这两个函数可以用来找到 map 中第一个大于等于(小于)指定键的元素,适用于查找某一键值范围内的所有元素。

std::map<std::string, int> grades = {{"Alice", 85}, {"Bob", 90}, {"Charlie", 95}, {"David", 98}};auto lower = grades.lower_bound("Bob");
auto upper = grades.upper_bound("David");for (auto it = lower; it != upper; ++it) {std::cout << it->first << ": " << it->second << std::endl;
}
// 输出:Bob: 90 Charlie: 95

22. 使用 emplace_hint 并结合 find 获取更好的插入性能

当已知要插入的位置附近时,可以先用 find 查找,然后将返回的迭代器作为 emplace_hint 的参数。

std::map<std::string, int> grades;
auto it = grades.find("Bob");
grades.emplace_hint(it, "Alice", 85); // 如果 "Bob" 已经在 map 中,那么 "Alice" 将插入在其之前

23. 使用 key_compvalue_comp 比较器

key_comp 返回一个可以用来比较键的仿函数,value_comp 返回一个可以用来比较元素(键值对)的仿函数。

std::map<std::string, int> grades;// 检查两个键是否按 map 的排序规则相等
if (grades.key_comp()("Alice", "Bob") == 0) {// ...
}// 检查两个键值对是否按 map 的排序规则相等
if (grades.value_comp()(std::make_pair("Alice", 85), std::make_pair("Bob", 90)) == 0) {// ...
}

24. 使用 equal_range 进行精确查找

equal_range 返回一个迭代器对,表示 map 中所有键等于给定键的元素范围,对于 map,这始终只包含一个元素。

auto range = grades.equal_range("Alice");
assert(range.first == range.second); // 如果 "Alice" 不存在于 map 中,两者相等

25. 使用 max_size 查询最大容量

max_size 函数返回 map 可能容纳的最大元素数量,但实际可用空间可能受系统限制影响。

std::size_t maxSize = grades.max_size();
std::cout << "Max possible size of grades map: " << maxSize << std::endl;

26. 使用 reserve 预留空间

虽然 map 不能像 vector 那样直接预留空间,但它会根据需要动态调整内部数据结构,以适应增加的元素。

27. 使用 extractemplace 实现原子化的更新操作

可以提取元素、修改其值,然后重新插入,确保在多线程环境下的原子性。

if (auto entry = grades.extract("Bob"); entry.second) {entry.mapped() = 92; // 修改值grades.emplace_hint(entry.position(), std::move(entry)); // 重新插入
}

28. 使用 extract 移除元素并转换为普通对象

extract 函数可以将 map 中的元素提取出来,并转换为一个普通的键值对(std::pair<const Key, T>)。

if (auto entry = grades.extract("Bob"); entry.second) {std::pair<const std::string, int> extractedPair = *entry;// 使用 extractedPair 进行进一步操作
}

29. 使用 extract 清空 map

可以通过连续调用 extract 并忽略返回值来清空 map。

while (!grades.empty()) {grades.extract(grades.begin());
}

30. 使用 std::transform 迭代 map 并应用函数

结合迭代器和 std::transform 函数,可以对 map 中的所有值执行某种计算。

std::map<std::string, int> gradesCopy;
std::transform(grades.begin(), grades.end(),std::inserter(gradesCopy, gradesCopy.end()),[](const auto& pair) {return std::make_pair(pair.first, pair.second * 2); // 示例:将成绩加倍});

以上示例展现了 std::map 更多的特性和用法,帮助开发者深入了解并有效地使用这一容器。

31. 使用 std::copy 将 map 转换为 vector

可以将 map 的键或值复制到 vector 中。

std::vector<std::string> keys;
std::copy(grades.begin(), grades.end(),std::back_inserter(keys),[](const auto& pair) { return pair.first; });std::vector<int> values;
std::transform(grades.begin(), grades.end(),std::back_inserter(values),[](const auto& pair) { return pair.second; });

32. 使用 std::all_of, std::any_of, std::none_of 对 map 进行条件检查

bool allAbove90 = std::all_of(grades.begin(), grades.end(),[](const auto& pair) { return pair.second > 90; });bool anyBelow80 = std::any_of(grades.begin(), grades.end(),[](const auto& pair) { return pair.second < 80; });bool noneEqual95 = std::none_of(grades.begin(), grades.end(),[](const auto& pair) { return pair.second == 95; });

33. 使用 std::accumulate 计算 map 中所有值的总和

int totalScore = std::accumulate(grades.begin(), grades.end(), 0,[](int sum, const auto& pair) { return sum + pair.second; });

34. 使用 std::for_each 对 map 进行遍历并打印

std::for_each(grades.begin(), grades.end(),[](const auto& pair) { std::cout << pair.first << ": " << pair.second << std::endl; });

35. 使用 std::map::extract 结合 std::set 移除特定键集合中的元素

std::set<std::string> studentsToRemove = {"Alice", "Bob"};
for (const auto& student : studentsToRemove) {if (auto it = grades.extract(student); it.second) {// 已成功移除学生}
}

36. 使用 std::map::emplace_hint 更新已存在的键值对

auto it = grades.find("Charlie");
if (it != grades.end()) {grades.emplace_hint(it, "Charlie", it->second + 1); // 假设将成绩增加1分
}

37. 使用 std::unordered_map 改善查找性能(散列映射)

在某些场景下,如果你不需要键有序且查找速度更为关键,可以考虑使用 std::unordered_map

std::unordered_map<std::string, int> unorderedGrades;
// ... 插入和访问方式类似 ...

38. 使用 std::map::key_typemapped_type 获取键和值的类型

using StudentName = std::map<std::string, int>::key_type;
using Grade = std::map<std::string, int>::mapped_type;

39. 使用 std::advance 移动迭代器

auto it = grades.begin();
std::advance(it, 2); // 移动到第三个元素的位置

40. 使用 std::prevstd::next 访问相邻元素

auto it = std::next(grades.begin()); // 第二个元素
auto previous = std::prev(it); // 第一个元素
auto next = std::next(it); // 第三个元素

请注意,在实际项目中,应结合具体情况合理使用这些技术,以达到代码简洁、高效的目的。

python推荐学习汇总连接:
50个开发必备的Python经典脚本(1-10)

50个开发必备的Python经典脚本(11-20)

50个开发必备的Python经典脚本(21-30)

50个开发必备的Python经典脚本(31-40)

50个开发必备的Python经典脚本(41-50)
————————————————

​最后我们放松一下眼睛
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/711396.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python音乐信息管理库之beets使用详解

概要 在数字化时代,音乐管理变得越来越重要,特别是对于音乐爱好者和专业音乐人士而言。Python作为一种功能强大的编程语言,拥有着丰富的音乐处理库,其中Beet就是一款备受推崇的音乐信息管理工具。本文将深入探讨Beet库的功能特性、使用方法以及应用场景,并提供丰富的示例…

WPF真入门教程31--WPF版房屋租售系统

1、教程回顾 到现在为止&#xff0c;“蒸”入门系列教程已完成了30刺由浅入深地讲解&#xff0c;当然不可能讲到了WPF的所有技能点&#xff0c;但读者看到了wpf的内部各种功能及之间的联系&#xff0c;在此基础上&#xff0c;再提供一个完整有效的综合项目&#xff0c;本项目采…

tcp的三次握手和四次挥手?

一&#xff1a;引出 客户端与服务器之间数据的发送和返回的过程当中需要创建一个叫TCP connection的东西&#xff1b;由于TCP不存在连接的概念&#xff0c;只存在请求和响应&#xff0c;请求和响应都是数据包&#xff0c;它们之间都是经过由TCP创建的一个从客户端发起&#xff…

身份验证错误。要求的函数不受支持。远程计算机:[IP地址]。这可能是由于CredSSP加密数据库修正

出现“身份验证错误。要求的函数不受支持。远程计算机&#xff1a;[IP地址]。这可能是由于CredSSP加密数据库修正”的问题&#xff0c;通常是因为Windows更新后&#xff0c;远程桌面连接&#xff08;RDP&#xff09;的安全性增强&#xff0c;特别是与CredSSP&#xff08;Creden…

[RoarCTF 2019]Easy Calc

这题考查的是: 字符串解析特性目录读取文件内容读取 字符串解析特性详解&#xff1a;PHP字符串解析特性 &#xff08;$GET/$POST参数绕过&#xff09;&#xff08;含例题 buuctf easycalc&#xff09;_参数解析 绕过-CSDN博客 ascii码查询表&#xff1a;ASCII 表 | 菜鸟工具 …

AI智能雷达名片小程序平台版源码系统 带完整的安装代码包以及安装部署教程

在当今数字化快速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;已渗透到各个领域&#xff0c;尤其是在商务沟通领域&#xff0c;传统的名片已经不能满足现代商业的需求。小编给大家分享一款名为“AI智能雷达名片小程序平台版”的源码系统&#xff0c;该系统不仅提…

知乎引流秘籍:玩转知乎,掘金百万流量!

知乎&#xff0c;拥有3亿注册用户、日新增用户8万的超级内容平台&#xff0c;已然成为流量洼地。如何玩转知乎&#xff0c;掘金百万流量&#xff1f;这份1500字的实操指南&#xff0c;为你揭秘&#xff01; 一、知乎的优势&#xff1a;流量大、长尾效应强 1. 流量大&#xff…

提升智能客服机器人的语义理解能力:理解用户的语义和意图

智能客服机器人的发展已经成为现代服务业的一大亮点。它们不仅能够提供724小时不间断的服务&#xff0c;而且能够处理大量的用户请求&#xff0c;大大提高了服务效率。然而&#xff0c;尽管智能客服机器人的技术已经取得了显著的进步&#xff0c;但其语义理解能力仍有待提高。为…

【Linux杂货铺】调试工具gdb的使用

目录 &#x1f308;前言&#x1f308; &#x1f4c1;背景介绍 &#x1f4c1; 使用 list [行号] / [函数名] run/r break/b [行号] / [函数名] info break disable break enable break delete break [断点编号] next/n step/s continue/c finish print/p [变量…

06 vim工具

目录 概念模式基本操作配置 1. 概念 vim是一个历史悠久的,多模式的编辑器&#xff0c;是vi的升级版。和ide不同&#xff0c;编辑器仅能编写文本&#xff0c;不能运行代码&#xff0c;现阶段的代码编译的各个过程会分开按步骤执行 2. 模式 vim有很多种模式&#xff0c;想要编…

方格分割644--2017蓝桥杯

1.用dfs解决&#xff0c;首先这题的方格图形就很像一个走迷宫的类型&#xff0c;迷宫想到dfs&#xff0c;最中心点视为起点&#xff0c;起点有两个小人在这个方格里面对称行动&#xff0c;直到走出迷宫&#xff08;一个人走出来了另一个人就也走出来了&#xff0c;而走过的点会…

Vmware Esxi 部署Mac OS虚拟机

Vmware Esxi在创建虚拟机的时候是有Mac OS选项的&#xff0c;但是实际创建时&#xff0c;选择ISO开机后一直反复引导&#xff0c;是有问题的&#xff0c;原因是需要先解锁&#xff0c;需要在ESXI主机上修改配置并重启。 首先找到管理-服务-TSM-ssh&#xff0c;点击启动&#x…

★【二叉搜索树(中序遍历特性)】【 ★递归+双指针】Leetcode 98. 验证二叉搜索树

★【二叉搜索树&#xff08;中序遍历特性&#xff09;】【 ★递归双指针】Leetcode 98. 验证二叉搜索树 二叉搜索树 98. 验证二叉搜索树解法1 笨 中序递归遍历为一个数组 然后判断数组是不是升序排列就可以★解法2 不使用数组 递归法 ---------------&#x1f388;&#x1f38…

php PhpSpreadsheet 读取日期变数字问题解决

问题描述&#xff1a; 使用PhpSpreadsheet 读取表格数据&#xff0c;日期格式读取后变成数字&#xff0c;如下图&#xff1a; 解决方案&#xff1a; $cell $sheet->getCell(H . $row)->getValue(); $toTimestamp \PhpOffice\PhpSpreadsheet\Shared\Date::excelToTimes…

腾轩科技传媒探讨网络整合营销推广的策略和效果

在当今高度信息化的商业环境中&#xff0c;整合营销推广&#xff08;IMC&#xff09;已经成为了品牌营销策略的核心。它旨在通过多种渠道和平台&#xff0c;将一致、连贯的品牌信息传达给目标受众&#xff0c;从而增强品牌知名度和忠诚度。腾轩科技传媒将深入探讨整合营销推广的…

【airtest】自动化入门教程(一)AirtestIDE

目录 一、下载与安装 1、下载 2、安装 3、打开软件 二、web自动化配置 1、配置chrome浏览器 2、窗口勾选selenium window 三、新建项目&#xff08;web&#xff09; 1、新建一个Airtest项目 2、初始化代码 3、打开一个网页 四、恢复默认布局 五、新建项目&#xf…

模拟算法题练习(一)

模拟算法介绍&#xff1a; 模拟算法通过模拟实际情况来解决问题&#xff0c;一般容易理解但是实现起来比较复杂&#xff0c;有很多需要注意的细节&#xff0c;或者是一些所谓很“麻模“的东西。 模拟题一般不涉及太难的算法&#xff0c;一般就是由较多的简单但是不好处理的部…

【算法】最小生成树—Prim算法与Kruskal算法

Prim算法和Kruskal算法都是解决最小生成树问题的经典算法。最小生成树是原图的最小连通子图&#xff0c;它包含原图的全部结点&#xff0c;且保持图连通的所有边代价和最小。一个连通图可能有多个最小生成树。 一、Prim算法 含义 Prim算法&#xff0c;也被称为普里姆算法&…

基于移动端的食堂助餐在线点餐配送系统 uniapp微信小程序

本文从管理员、老人、配送员、食堂商家的功能要求出发&#xff0c;养老助餐管理系统小程序中的功能模块主要是实现老人、配送员、食堂商家、食堂大厅、预约选座、餐号信息、美食信息、美食订单、订单信息、订单配送、订单评价、老人食堂、下单信息、饮食分析。经过认真细致的研…

C语言可以干些什么?C语言主要涉及哪些IT领域?

C语言可以干些什么&#xff1f;C语言主要涉及哪些IT领域&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C语言的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家…