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;uMap["math"]=100;
uMap["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对象来复制键值,而这会导致不必要的内存分配和拷贝操作。
代码编写
while(n--)
{//输入key和doorcin>>key>>door;//将key和对应的door放进map中umap[key]=door;
}
设置一个flag,用来标志是否找到匹配的键值对
bool flag=true;
遍历map,判断当前键值对中的值是否等于输入的值,如果等于,则将键输出并退出
for(const pair<int,int>&kv:umap)
{//检查当前键值对中的值是否等于xif(kv.second==x){cout<<kv.first<<endl;//如果找到了匹配的键值对,将kv.first输出到标准输出,并换行flag=false;break;}
}
因此,本题的源代码是:
#include <iostream>
#include <unordered_map>using namespace std;int main()
{int s,n,key,door,x;cin>>s;while(s--){unordered_map<int,int> umap;cin>>n;while(n--){cin>>key>>door;umap[key]=door;}cin>>x;bool flag=true;for(const pair<int,int>&kv:umap){if(kv.second==x){cout<<kv.first<<endl;flag=false;}}if(flag){cout<<"Can't open the door."<<endl;}}
}