map 在c++中翻译为映射。
map 是STL(标准模板库)的一个关联容器(字典)。
是有序键(key)值(value)对容器。
map的键(key)是索引,不能重复,一个键(key)对应着一个值(value);
value为关键字的值,可以重复。不同的学生学号不同,但是体重相同一样。
map中的元素会自动排序(默认按照升序排序),并且增删改查整体上都很快。
- 使用map必须包含头文件:
#include<map>
map的定义与初始化
格式为
map<keyType,valueType> myMap;
其中, keyType为键的类型(这种类型要求能够比较大小)。
其中,valuetype 为值的类型(没什么要求)。
示例
定义一个key和value的类型都是整数的map,存放学生的学号和成绩:
map<int, int> student_score{
//学号不可以有重复
//学号可以不按顺序创建
//学号在创建完成之后会在内部自动排好顺序
//学号排序按照大小顺序,int类型的数据就按数值大小排序
{003, 90},
{004, 88},
{001, 88},//分数可以有相同的分数
{002, 78},
};
可以看出初始化map的时候,key并不是按照顺序创建的,但是创建完成以后在内存中的map(如上图)是排好顺序的。
map的元素与遍历
map的元素是一个key和一个value共同构成的组合体,这个组合体是一个pair<int,int> 类型。
pair<int, int> 类型有两个成员:first,second。
下面的例子先通过for循环遍历map,再用first和second访问元素的key和value。
#include <iostream>
#include <map>
using namespace std;
//本利中map的元素类型
/*
struct pair
{
int first;
int second;
};
*/
int main(int argc, char** argv)
{
map<int, int> student_score{
//学号不可以有重复
//学号可以不按顺序创建
//学号在创建完成之后会在内部自动排好顺序
//学号排序按照大小顺序,int类型的数据就按数值大小排序
{003, 90},
{004, 88},
{001, 88},//分数可以有相同的分数
{002, 78},
};
//item变量来迭代student_score 的每一个元素
for (auto item : student_score)
{
//item是一个pair<int, int>类型
cout << "id=" << item.first << " " << " score=" << item.second << endl;
}
return 0;
}
可见,输出的时候元素会按照顺序输出。
访问元素
下面的例子中,我们实现一个大学的简称和全称对应关系的map。
key类型为string,value类型也为string:
map<string, string> universities;
通过下标访问元素
下面的下标访问会得到这个key对应的值value(值是一个变量)
universities["MIT"];
通过范围 for 循环访问元素
下面的item会遍历到map的每一个元素。
for(auto& item : universities);
可以通过item.first 访问键,item.second 访问值。
插入元素
使用下标操作符插入元素
universities["MIT"] = "麻省理工学院 Massachussets Institute of Technology";
上面的代码看起来是给元素赋值,实际上如果这个元素不存在,则会先创建这个元素(键值对)。所以,下标操作非常方便。
但是,也可能会误加元素到map里。
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<string, string> universities;
/*下面的代码完成了元素创建的工作,因为map中还没有这个元素
*/
universities["MIT"] = "麻省理工学院 Massachussets Institute of Technology";
cout <<"size="<< universities.size() << endl;//可见元素数量是1了
cout << universities["MIT"] << endl;//可以取出这个key为“MIT”的元素的value并输出
return 0;
}
输出:
使用insert成员函数插入元素
universities.insert({"MIT", "麻省理工学院 Massachussets Institute of Technology"});
效果和使用中括号版本相同:
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<string, string> universities;
/*下面的代码,使用insert成员函数插入一个键值对
*/
universities.insert({ "MIT", "麻省理工学院 Massachussets Institute of Technology" });
cout <<"size="<< universities.size() << endl;
cout << universities["MIT"] << endl;
return 0;
}
完整的例子
看下面的例子就明白了:
#include <iostream>
#include <string>
#include <map>
using namespace std;
//本利中map的元素类型
/*
struct pair
{
string first;
string second;
};
*/
int main(int argc, char** argv)
{
//初始化map
//map会自动对插入的元素按照key大小进行排序
//这里key是string类型,所以使用string的小于号来排序
//string的小于号比较大小按照ASCII码的字母表排序
map<string, string> universities{
{"MIT", "麻省理工学院 Massachussets Institute of Technology"},
{"UCB", "加州大学伯克利分校 University of California - Berkeley"},
{"CMU", "卡内基梅隆大学 Carnegie Mellon University"},
{"CC", "哥伦比亚大学 Columbia University /Community College"},
{"CU", "康奈尔大学 Cornell University"},
{"UNC", "北卡罗来纳大学 University of North Carolina - Chapel Hill"},
{"UWM", "威斯康辛大学麦迪逊分校 University of Wisconsin - Madison"},
{"GWU", "乔治华盛顿大学 George Washington University"},
{"JHU", "约翰霍普金斯大学 Johns Hopkins University"},
{"MSU", "密歇根州立大学 Michigan State University"},
};
//运行时根据业务需要,插入一条记录
universities["Penn"] = "宾夕法尼亚大学 University of Pennsylvania";
//按照字母表顺序输出所有大学
cout << "All " << universities.size() << " universities:" << endl;
for (auto& item : universities)
{
cout<<"key=" << item.first << " , value= " << item.second << endl;
}
return 0;
}
程序输出
可以看出:
- map的每一个元素包括两部分key和value;
- key在插入后就不再可以改变,可以被删除(同时对应的value一起被删除);
- key对应的value可以被访问和读写;
- map使用中括号[]操作符来获取key对应的value;
- map的元素在插入的过程中会自动排序(使用小于号<对元素按照key排序)。
更全面的介绍参考:map - C++ Reference
multimap
标准库同时还提供了key可以重复的关联容器multimap,参考: