map

std::map 是 C++ 标准库(STL)中的有序关联容器,用于存储键值对(key-value pairs),其核心特性是基于键(key)的自动排序键的唯一性(每个键在 std::map 中仅能出现一次)。

一、核心特性

  1. 有序性
    内部通过红黑树(Red-Black Tree) 实现(一种自平衡二叉搜索树),插入元素后会自动根据键的比较规则(默认是 std::less<Key>,即升序)排序,支持高效的有序遍历和范围查询。

  2. 键唯一性
    不允许存在重复的键,若插入已存在的键,新值会覆盖旧值(通过 insert 插入重复键会失败,通过 [] 赋值会覆盖)。

  3. 高效操作
    插入、删除、查找操作的时间复杂度均为 O(log n)(n 为元素个数),远优于 std::vector 的 O (n) 操作(适用于频繁增删和查询的场景)。

  4. 键不可修改
    键(key)在插入后无法直接修改(若需修改,需先删除旧键值对,再插入新键值对),但值(value)可以修改。

  • 双向迭代器map 提供了双向迭代器,可以向前和向后遍历元素。

基本语法

包含头文件:

#include <map>

声明 map 容器:

std::map<key_type, value_type> myMap;
  • key_type 是键的类型。
  • value_type 是值的类型。

插入元素:

myMap[key] = value;

访问元素:

value = myMap[key];

for循环遍历

#include <iostream>
#include <map>

int main()
{	
	std::map<std::string, int> myMap;

	myMap["身高"] = 180;
	myMap["体重"] = 70;

	int height = myMap["身高"];
	std::map<std::string, int>::iterator it;
	for (it = myMap.begin(); it != myMap.end(); ++it)
	{
		std::cout << it->first << "=>" << it->second << std::endl;
	}
	return 0;
}

输出

身高=>180
体重=>70

C++11及以上标准,遍历部分可以简化为范围for循环,代码更简洁

for (auto& p : myMap) {
	std::cout << p.first << " : " << p.second << std::endl;
}

进阶用法

检查键是否存在:

if (myMap.find(key) != myMap.end()) {
    // 键存在
}

删除元素:

myMap.erase(key);

清空 map:

myMap.clear();

获取 map 的大小:

size_t size = myMap.size();

其他方法:

myMap.empty();      // 是否为空
myMap.count("Bob"); // key 是否存在(返回 0 或 1)

自定义排序,默认升序排序,可以用 std::greater 或自定义比较函数:

std::map<int, std::string, std::greater<int>> m;  // 降序

map 是 C++ STL 中一个非常有用的容器,特别适合需要快速查找和有序数据的场景。

unordered_map

在 C++ 中,<unordered_map> 是标准模板库(STL)的一部分,提供了一种基于哈希表的键值对容器。与 std::map 不同,unordered_map 不保证元素的排序,但通常提供更快的查找速度。

unordered_map 是一个关联容器,它存储了键值对(key-value pairs),其中每个键(key)都是唯一的。unordered_map 使用哈希表来存储元素,这使得它在查找、插入和删除操作中具有平均常数时间复杂度。

语法

以下是 unordered_map 的基本语法:

#include <unordered_map>

std::unordered_map<key_type, value_type> map_name;
  • key_type 是键的类型。
  • value_type 是值的类型。

基本操作

插入元素:

myMap.insert({3, "three"});

访问元素:

std::string value = myMap[1]; // 获取键为1的值

实例如下

#include <iostream>
#include <unordered_map>

int main()
{	
	std::unordered_map<int, std::string> myMap;
	// 插入一些键值对
	myMap[1] = "one";
	myMap[2] = "two";
	myMap[3] = "three";
	// 打印所有元素
	for (const auto& pair : myMap) {
		std::cout << "Key:" << pair.first << ",Value: " << pair.second <<  std::endl;
	}
	// 访问特定键的值
	std::cout << "Value for key 2: " << myMap[2] << std::endl;

	myMap.erase(1);

	// 再次打印所有元素
	std::cout << "After erasing key 1:" << std::endl;
	for (const auto& pair : myMap) {
		std::cout << "Key: " << pair.first << ", Value: " << pair.second << std::endl;
	}
	return 0;
}

注意事项

  • unordered_map 不保证元素的顺序,因此元素的迭代顺序可能在不同的运行中不同。
  • 哈希表的性能依赖于良好的哈希函数,以避免过多的哈希冲突。
  • 与 std::map 相比,unordered_map 在元素数量较少时可能占用更多的内存。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐