开房门
时间限制:1.000S 空间限制:128MB
题目描述
假设你手里有一串钥匙,这串钥匙上每把钥匙都有一个编号,对应着一个房门的编号。现给你一个房门编号,你需要判断是否能够打开该房门。
输入描述
测试数据共有多组。
第一行为一个整数 s,表示共有多少组测试数据。
每组第一行有一个整数 n,表示钥匙串上有多少把钥匙。
后面共有 n 行输入,每行两个整数,第一个整数 k 表示钥匙编号,第二个整数 d 表示房门编号。
最后一行有一个整数 x,表示需要打开的房门编号。
输出描述
输出多组,每组占一行。 如果能打开,则输出钥匙编号,不能打开则输出“Can't open the door.”。
输入示例
2
5
878788 9373833
837837 3837378
378338 3398939
388733 2329389
878373 3938399
3938399
3
998389 3892393
444323 3892783
883782 5334332
8739833
输出示例
878373
Can't open the door.
本节课我们来学习哈希表的最后一种实现map
映射, 具体包括下列内容
map、``unordered_map
,multimap
概念和特点map、``unordered_map
,multimap
的基本操作,比如创建、插入、删除、查找- 范围for循环
map的基本介绍
我们常常把map
称之为映射,就是将一个元素(通常称之为key
键)与一个相对应的值(通常称之为value
)关联起来,比如说一个学生的姓名(key
)有与之对应的成绩(value
),它们是一一对应的,就好像一把钥匙开一扇门,在map
中键是唯一的,也只有一个唯一的确定的值。
在C++中, map 提供了以下三种数据结构,其底层实现以及优劣如下表所示:
map
中的键是唯一的,但是multimap
则没有此限制
映射 | 底层实现 | 是否有序 | 数值是否可以重复 |
---|---|---|---|
std::map | 红黑树 | key有序 | key不可重复 |
std::multimap | 红黑树 | key有序 | key可重复 |
std::unordered_map | 哈希表 | key无序 | key不可重复 |
std::unordered_map
的key值存储是无序的,底层实现为哈希表,查找速度更快,如果不需要排序而只是快速查找键对应的值,可以考虑使用。
std::map 和std::multimap
的底层实现是红黑树,它的key值存储是有序的,如果需要对键值对进行自定义排序,可以考虑使用std::map
。
map的使用
使用映射容器需要引入头文件<unordered_map>
或者<map>
// 引入unordered_map头文件,包含unordered_map类型
#include <unordered_map>
// 引入map头文件,包含map类型和multimap类型
#include <map>
想要声明map映射
关系,需要指定键的类型和值的类型。
// 声明一个整数类型映射到整数类型的 无序映射
unordered_map<int, int> uMap;
// 声明一个将字符串映射到整数的`map`,可以这样声明:
map<string, int> myMap;
想要插入键值对key-value
, 需要使用insert()
函数或者使用[]
操作符来插入。如果键不存在,[]
操作符将会创建一个新的键值对,将其插入到map
中,并将值初始化为默认值(对于整数来说,默认值是0)。
uMap[0] = 10;
uMap[10] = 0;myMap["math"] = 100;
myMap["english"] = 80;
和set
类似,可以使用find
函数来检查某个键是否存在于map
中,它会返回一个迭代器。如果键存在,迭代器指向该键值对,否则指向map
的末尾。
if (myMap.find("math") != myMap.end()) {// 键存在
} else {// 键不存在
}
你可以使用范围for循环
来遍历map
中的所有键值对,进行各种操作。
for(const pair<int,int>& kv:umap) {}
当使用范围for循环遍历map
时,我们需要声明一个变量kv
来存储每个键值对。这个变量的类型通常是pair
类型,下面就让我们详细解释一下const pair<int,int>& kv:umap
const
用于声明一个不可修改的变量,这意味着一旦变量被初始化,就不能再修改其值。常量通常用大写字母表示
因为const声明的变量一旦创建后就无法修改值,所以必须初始化。
const double PI = 3.1415926;
在这里,const
关键字表示你只能读取容器中的元素,而不能修改它们。
而pair<int, int>
定义了kv
也就是键值对的数据类型是pair
, C++中的pair
类型会将两个不同的值组合成一个单元, 常用于存储键值对,创建pair
的时候,也必须提供两个类型名,比如上面的pair
对象,两个值的类型都是int
, 在使用时通过first
和 second
成员来访问 pair
中的第一个和第二个元素, 它的 first
成员存储键,而 second
成员存储值。
&
:这个符号表示kv
是一个引用(reference),而不是值的拷贝, 如果不使用引用的话,那在每次循环迭代中都会重新创建一个新的pair
对象来复制键值对,而这会导致不必要的内存分配和拷贝操作。
C++代码实现:
#include<iostream>
using namespace std;
#include<unordered_map>int main(){int s, n, k, d, x;cin >> s; // 输入测试用例的数量while(s--){unordered_map<int, int> umap; // 创建一个无序映射容器 umapcin >> n; // 输入每个测试用例中键值对的数量while(n--){cin >> k >> d; // 输入键值对的键和值umap[k] = d; // 将键值对插入到 umap 中}cin >> x; // 输入要查找的值bool flag = true; // 标记是否找到匹配的键值对for(const pair<int, int>& key : umap){if(key.second == x){ // 如果找到匹配的值cout << key.first << endl; // 输出对应的键flag = false; // 将标记设置为 false,表示找到匹配的键值对break; // 跳出循环}}if(flag) // 如果没有找到匹配的键值对cout << "Can't open the door." << endl; // 输出提示信息}return 0;
}