C++ 标准模板库 (STL) 中的 Map
C++ 中的 Map 是什么?语法
在 C++ 中,MAP 是一种关联容器,以映射形式存储项。Map 中的每个项都由键值和映射值组成。两个映射值不能共享相同的键值。
键值非常适合用于排序和唯一标识元素。映射值用于存储与键关联的内容。两者类型可能不同,但成员类型通过组合两者的 pair 类型将其组合起来。
为什么使用 std::map?
使用 Map 的原因如下:
- std:: map 仅根据选择的排序标准以排序顺序存储唯一键。
- 使用键可以轻松快速地搜索元素。
- 每个键只附加一个元素。
- std::map 可以用作关联数组。
- std::map 可以使用二叉树(平衡)来实现。
语法
要声明 std::map,请使用此语法
std::map<key_datatype, value_datatype>map_name;
key_datatype
表示 map 键的数据类型。value_datatype
表示与 map 键相对应的值的数据类型。map_name
是 map 的名称。
例如
map<string, int> my_map;
我们声明了一个名为 my_map
的 map。该 map 将字符串作为键数据类型,并将整数作为值数据类型。
成员类型
成员函数可以使用以下成员类型作为参数或返回类型
- key_type: 键(模板中的第一个参数)
- mapped_type: T(模板中的第二个参数)
- key_compare: Compare(模板中的第三个参数)
- allocator_type: Alloc(模板中的第四个参数)
- value_type: pair<const key_type,mapped_type>
- value_compare: 用于比较元素的嵌套函数类
- reference: allocator_type::reference
- const_reference: allocator_type::const_reference
- pointer: allocator_type::pointer
- const_pointer: allocator_type::const_pointer
- iterator: 指向 value_type 的双向迭代器
- const_iterator: 指向 const value_type 的双向迭代器
- reverse_iterator: 反向迭代器
- const_reverse_iterator: 常量反向迭代器
- difference_type: ptrdiff_t
- size_type: size_t
std::map 的内置函数
std::map 带有内置函数。其中一些包括:
- begin() – 此函数返回指向 map 第一个项的迭代器。
- size() –此函数返回 map 中的项数。
- empty() –此函数返回一个布尔值,表示 map 是否为空。
- insert( pair(key, value)) – 此函数将新的键值对插入到 map 中。
- find(val) – 如果找到 val 元素,此函数将返回指向该元素的迭代器。否则,它将返回 m.end()。
- erase (iterator position) –此函数删除迭代器指向的项。
- erase(const g) – 此函数从 map 中删除键值 g。
- Clear () –此函数删除 map 中的所有项。
遍历 Map 元素
您可以遍历 map 元素。我们只需创建一个迭代器并使用它即可。
例如
示例 1
#include <iostream> #include <string> #include <map> using namespace std; int main() { map<int, string> Students; Students.insert(std::pair<int, string>(200, "Alice")); Students.insert(std::pair<int, string>(201, "John")); cout << "Map size is: " << Students.size() << endl; cout << endl << "Default map Order is: " << endl; for (map<int, string>::iterator it = Students.begin(); it != Students.end(); ++it) { cout << (*it).first << ": " << (*it).second << endl; } }
输出
这是代码的屏幕截图:
代码解释
- 将 iostream 头文件包含到我们的代码中以使用其函数。
- 将 string 头文件包含到我们的代码中以使用其函数。
- 将 map 头文件包含到我们的代码中以使用其函数。
- 将 std 命名空间包含到我们的代码中,以便在使用其类时无需显式调用 std。
- 调用
main()
函数。{ 标记函数体的开始。 - 创建一个名为 Students 的 map,其中键为整数,值为字符串。
- 向 Students map 中插入值。键为 200,值为 Alice 将被插入到 map 中。
- 向 Students map 中插入值。键为 201,值为 John 将被插入到 map 中。
- 使用
size()
函数获取名为 Students 的 map 的大小。这应该返回 2。 - 在控制台打印一些文本。
- 使用 for 循环创建一个名为 it 的迭代器来遍历名为 Students 的 map 的元素。
- 将 Students map 的值打印到控制台。
- for 循环体结束。
main()
函数体的结束。
在 std::map 中插入数据
您可以使用 insert()
函数向 std::map 输入项。请记住,std::map 键必须是唯一的。
因此,它首先检查 map 中是否已存在每个键。如果存在,则不会插入该条目,但会返回现有条目的迭代器。如果不存在,则会插入该条目。
该函数有以下变体
- insert(pair) – 使用此变体,将键值对插入 map 中。
- insert(start_itr, end_itr) – 使用此变体,条目将从另一个 map 插入到由 start_itr 和 end_itr 定义的范围内。
insert_or_assing() 函数的作用与 insert()
函数相同,但如果给定的键已存在于 map 中,则其值将被修改。
示例 2
#include <map> #include <iostream> using namespace std; int main() { map<int, int> m{ {1,3} , {2,4} , {3,5} }; m.insert({ 5, 6 }); m.insert({ 1, 8 }); m.insert_or_assign(1, 6); cout << "Key\tElement\n"; for (auto itr = m.begin(); itr != m.end(); ++itr) { cout << itr->first << '\t' << itr->second << '\n'; } return 0; }
输出
这是代码的屏幕截图:
代码解释
- 将 map 头文件包含到我们的代码中以使用其函数。
- 将 iostream 头文件包含到我们的代码中以使用其函数。
- 将 std 命名空间包含到我们的代码中,以便在使用其类时无需显式调用 std。
- 调用
main()
函数。{ 标记函数体的开始。 - 创建一个名为 m 的 map,其中键为整数,值为整数。已向 map 添加三个条目。
- 向 map m 中插入一个新条目。键为 5,值为 6 将被插入到 map 中。
- 尝试向已存在的键中添加条目。由于键 1 已存在于 map 中,因此不会添加该条目。
- 使用
insert_or_assign()
函数插入或修改现有条目。由于键 1 已存在,因此其值将更改为 6。 - 在控制台打印一些文本。“\t”字符创建水平空格,而“\n”字符将光标移到下一行。
- 使用 for 循环创建一个名为 itr 的迭代器,用于遍历名为 m 的 map 的元素。
- 将 map m 的值打印到控制台。“\t”字符在每个键及其相应值之间创建水平空格。相比之下,“\n”字符在每次迭代后将光标移到下一行。
- for 循环体的结束。
- 程序在成功完成后应返回值。
main()
函数体的结束。
在 Map 中搜索
我们可以使用 find()
函数通过键来搜索 map 中的元素。如果未找到键,则函数返回 std::map::end。否则,将返回搜索元素的迭代器。
示例 3
#include <iostream> #include <string> #include <map> using namespace std; int main() { map<int, string> Students; Students.insert(std::pair<int, string>(200, "Alice")); Students.insert(std::pair<int, string>(201, "John")); std::map<int, string>::iterator it = Students.find(201); if (it != Students.end()) { std::cout << endl << "Key 201 has the value: => "<< Students.find(201)->second << '\n'; } }
输出
这是代码的屏幕截图:
代码解释
- 将 iostream 头文件包含到我们的代码中,以便使用其函数而不出错。
- 将 string 头文件包含到我们的代码中,以便使用其函数而不出错。
- 将 map 头文件包含到我们的代码中,以便使用其函数而不出错。
- 将 std 命名空间包含到我们的代码中,以便在使用其类时无需显式调用 std。
- 调用
main()
函数。{ 标记main()
函数体的开始。 - 创建一个名为 Students 的 map,其键为整数,值为字符串。
- 向 Students map 中插入值。键为 200,值为 Alice 将被插入到 map 中。
- 向 Students map 中插入值。键为 201,值为 John 将被插入到 map 中。
- 查找与键 201 相关联的值。
- 使用 if 语句检查是否找到了键对应的值。
- 在控制台上打印键的值以及一些文本。
- if 语句体的结束。
main()
函数体的结束。
从 Map 中删除数据
我们可以使用 erase()
函数从 map 中删除值。我们只需创建一个指向要删除的元素的迭代器。然后将该迭代器传递给 erase()
函数。
示例4
#include <iostream> #include <string> #include <map> using namespace std; int main() { map<std::string, int> my_map; my_map.insert(std::make_pair("cow", 1)); my_map.insert(std::make_pair("cat", 2)); my_map["lion"] = 3; map<std::string, int>::iterator it = my_map.find("cat"); my_map.erase(it); for (map<string, int>::iterator it = my_map.begin(); it != my_map.end(); ++it) cout << (*it).first << ": " << (*it).second << endl; return 0; }
输出
这是代码的屏幕截图:
代码解释
- 将 iostream 头文件包含到我们的代码中以使用其函数。
- 将 string 头文件包含到我们的代码中以使用其函数。
- 将 map 头文件包含到我们的代码中以使用其函数。
- 将 std 命名空间包含到我们的代码中,以便在使用其类时无需显式调用 std。
- 调用
main()
函数。{ 标记main()
函数体的开始。 - 创建一个名为 my_map 的 map,其键为字符串,值为整数。
- 向 my_map map 中插入值。键为 Cow,值为 1 将被插入到 map 中。
- 向 my_map map 中插入值。键为 Cat,值为 2 将被插入到 map 中。
- 向 my_map map 中添加值为 3,键为 lion。
- 创建一个迭代器来遍历 my_map map,查找键 cat。
- 删除迭代器指向的元素。
- 使用迭代器从头到尾遍历 my_map map 的元素。
- 将 my_map map 的内容打印到控制台。
- 程序成功完成后必须返回输出。
main()
函数体的结束。
摘要
- Map 是一种以映射形式存储项的关联容器。
- Map 中的每个项都有一个键值和一个映射值。
- 在 Map 中,两个映射值不能共享键值。
- 键值有助于排序和唯一标识元素。
- 映射值有助于存储与键关联的内容。
- C++ map 以排序顺序存储唯一键。
- 为了处理 C++ map,我们创建一个迭代器来遍历元素。
- 使用迭代器,我们可以执行诸如搜索和删除 map 中的项等任务。