关联容器map
- map: 是一个 key-value 键值对的集合,可以把它理解为关联数组,把 key理解为数组的下标,通过key获得值。
例如:
#include <map> //需要包含该头文件
//是一个 key-value 键值对的集合,可以把它理解为关联数组,把 key理解为数组的下标,通过key获得值
map<int, string> m1;
//key 1,2,3 把key理解为索引
m1[1] = "hello";
m1[2] = "tom";
m1[3] = "haha";
map的定义
map<string, string> m; //定义一个空map
map<string, string> m2(m); //定义一个map的副本
map<string, string> m3(m.begin(), m.end()); //通过迭代器定义
map定义的类型
map<int, string> m1;
m1[1] = "hello";
m1[2] = "tom";
m1[3] = "haha";
map<int, string>::value_type p = *m1.begin(); //pair类型
map<int, string>::key_type k = p.first; //键的类型
map<int, string>::mapped_type v = p.second; //值的类型
cout<<k<<endl; //输出为:1
cout<<v<<endl; //输出为:hello
map的遍历
方法一:
for(auto e:m1){
cout<< e.first << " "<<e.second<<endl;
}
方法二:使用迭代器
map<int, string>::iterator it = m1.begin();
while (it!=m1.end()) {
cout<<it->first<<" "<<it->second<<endl;
it++;
}
map的添加
map<int, string> m1;
m1.insert(make_pair(1, "hello"));
m1.insert(make_pair(2, "tom"));
m1.insert(make_pair(3, "haha"));
m1.insert(make_pair(3, "heheehe")); //注意:该语句失效,因为key值要唯一,当已经有一个对应的key时,再次insert是无效的。
map的删除
m1.erase(m1.begin());
map的应用
- 在机试中,其功能为:将一个类型的变量映射至另一类型。
例如:
产生冠军
思路:
- 将选手对应结点,胜负关系对应为结点之间的有向边,可以产生冠军的情况即为全图中入度为零的点唯一。
- 与普通的拓扑排序问题不同,这里我们需要将输入的选手姓名映射为结点编号,这就需要标准对象map。
#include <stdio.h>
#include <map>
#include <string>
using namespace std;
int in[2002]; //类似于hash,把各个名字对应的入度保存在in数组内;但是姓名无法用来当做下表索引,所以使用 map<string, int>来把string向int转换,从而可以通过int型对in数组置相应的入度。
int main(int argc, const char * argv[]) {
int n;
while (scanf("%d", &n)!=EOF&&n!=0) {
for (int i=0; i<2*n; i++) {
in[i] = 0; //初始化入度,一定要初始化,不然报错
}
map<string, int> m;
m.clear();
int it=0;
for (int i=0; i<n; i++) {
char str1[50], str2[50];
scanf("%s%s", str1, str2);
string a = str1;
string b = str2; //string不能使用scanf输入,所以先用char[]输入,然后再赋值给string
if (m.find(a)==m.end()) { //若map中尚无该a的映射
m[a] = it++; //设定其映射为it,并递增it
}
if (m.find(b)==m.end()) { //若map中尚无b的映射
m[b] = it++; //设定其映射为it,并递增it
}
int t = m[b];
in[t]++; //将b对应的in数组入度加一
}
int ans = 0;
for (int i=0; i<it; i++) { //确定所有影射数字的入度,统计入度为0的个数
if (in[i]==0) {
ans++;
}
}
if (ans==1) { //若入度为0的点的个数为1,则输出yes,否则输出no
puts("Yes");
}
else
puts("No");
}
return 0;
}
以上map的用法:
map<string, int> M; //定义一个完成从string到int映射的map
M.clear(); //清空一个map
M.find(b); //确定map中是否保存string对象b的映射,若没有函数返回M.end()
M[b] = it; //若map中不存在string对象b的映射,则定义其为it;
t = M[b]; //若map中存在string对象的映射,则读出该映射
另外一个在全排列中使用map的例子:
回溯法解全排列