- map容器
- map容器的类型
- 头文件
- map的创建和初始化
- 1 创建
- 2 初始化
- 3 Insert插入元素
- 4 emplace构造元素
- 4.1emplace
- 4.2 emplace_hint
- 5 map元素访问
- 6 erase/clear 删除元素
- Pair
- Tuple
map容器
是关联容器的一种,由键值对象组成,即 map 容器的元素是 pair
map容器的类型
-
map
容器,保存的是 pair 类型的元素。pair 封装了一对键对象,键的类型是 K,对象的类型是 T。每个键都是唯一的,所以不允许有重复的键;但可以保存重复的对象,只要它们的键不同。map 容器中的元素都是有序的,元素在容器内的顺序是通过比较键确定的。默认使用 less 对象比较。 -
multimap
容器和 map 容器类似,也会对元素排序。它的键必须是可比较的,元素的顺序是通过比较键确定的。和 map 不同的是,multimap 允许使用重复的键。因此,一个 multimap 容器可以保存多个具有相同键值的 元素。 -
unordered_map
中 pair< const K,T>元素的顺序并不是直接由键值确定的,而是由键值的哈希值决定的。哈希值是由一个叫作哈希的过程生成的整数,本章后面会解释这一点。unordered_map 不允许有重复的键。 -
unordered_multimap
也可以通过键值生成的哈希值来确定对象的位置,但它允许有重复的键。
区别
- multi前缀表明键不必唯一,但如果没有这个前缀,键必须唯一。
- unordered_prefix 前缀表明容器中元素的位置是通过其键值所产生的哈希值来决定的,而不是通过比较键值决定的。如果没有该前缀,那么元素的位置就由比较键值决定。
头文件
#include
map的创建和初始化
1 创建
//map
map people;
map默认构造函数有四个参数,但常常只初始化前两个参数,用于构造pair对象,因为map容器里面的对象都是pair
2 初始化
2.1 初始化列表,隐式的转化为pair对象
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
2.2 make_pair显示的构造pair对象初始化
map people{make_pair("Ann",25),make_pair("Bill", 46),make_pair("Jack", 32),make_pair("Jill", 32)};
2.3 容器拷贝
map peopelCopy {people};
//类型必须一致
2.4 迭代器初始化
mappeopleCopy2{people.begin(),people.end()}
代码实例
int main()
{
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
map peopleCopy{people.begin(), people.end()};
for(auto &i:peopleCopy)
{
cout << i.first << " "<
3 Insert插入元素
3.1 初始化列表插入
由于map默认是按照less 从小到大排序的,因此插入不指定插入位置。
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
people.insert({"Hon",3});
3.2 make_pair构造pair对象插入
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
auto pr = make_pair("Hon",3);
auto ret_pr = people.insert(pr);
说明:
1 make_pair返回值是一个pair对象
2 insert的返回值仍然是一个pair对象, pair 的成员变量 first 是一个指向插入元素或阻止插入的元素的迭代器;成员变量 second 是个布尔值,如果元素插入成功,second 就为 true。
cout<first<<" "<second<
3.3 直接使用pair对象插入,右值移动
people.insert(pair{"Hon", 3});
4 emplace构造元素
4.1emplace
emplace和insert的区别在于 emplace可以在适当的位置直接构造新元素,从而避免复制和移动操作,返回值同insert。
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
auto ret_pr = people.emplace("Kiss",9);
4.2 emplace_hint
emplace_hint() 调用使用一个迭代器作为指示符,指向先前 emplace() 调用返回的 pair 对象。如果容器使用这个提示符,那么新元素会在这个指示符表示的位置之前生成,并尽可能靠近这个位置。提示符后面的参数用来构造新元素。需要注意的是,它和 emplace() 的返回值是不一样的。emplace_hint() 的返回值不是一个 pair 对象,如果新元素被插入,它返回的是指向新元素的迭代器;如果没有插入,返回的是和这个键匹配的现有元素的迭代器,拥有相同的 key 值,如果不是现有元素的话。没有提示可以直接判断是否生成了新元素。唯一的方法是,用 size() 成员函数来获取 map 中对应元素的数量来检查 map 元素增加的数量
auto pr = people.emplace("Kiss",9);
auto iter = people.emplace_hint (pr.first,"Gine", 62);
5 map元素访问
5.1 迭代器
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
auto it = people.begin();
while (it != people.end())
{
cout << (*it).first << " " << (*it).second << endl;
it++;
}
5.2 at(key)
由于at()一般会检查边界,因此要对key做异常处理
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
string key;
try
{
key = "Anni";
cout << people.at(key) << endl;
key = "Ai";
cout << people.at(key) << endl;
}
catch (const out_of_range &e)
{
cerr << e.what() << endl;
}
-------------------------------------
12
invalid map key
5.3 [key]
下标运算符返回一个和 键关联的对象的引用,如果key指定的对象不存在,创建一个pair对象,值为0
cout<
由于[key]返回的是引用,因此可以通过=修改key对应的值
people["Ai"]=2;
cout<
6 erase/clear 删除元素
6.1 erase(key)
键作为参数传递,erase 返回值是删除元素的个数,如果没有对应key返回0,否则返回1
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
string key{"Anni"};
if(people.erase(key))
cout<<"erase success"<
6.2 erase(iteration)
迭代器作为参数,返回值为迭代器,返回的迭代器指向被删除元素的下一个位置(注意是排好序的),
如果删除元素是最后一个元素,返回的迭代器指向最后一个元素。
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
auto it = people.begin();
auto pr = people.erase(it);
cout << (*pr).first <<" " << (*pr).second<< endl;
-----------------------------------------
Bob 10 //注意排序
还可以删除迭代器指定范围内的元素 erase(start_iter,end_iter);
6.3 clear()
删除所有元素
map people{{"Anni",12},{"Joe",20},{"Bob",10}};
cout<
Pair
头文件:pair是包含在头文件utility中的,map头文件又包含了utility
#inclue
或者
#include
part
pair p1{10,6}
pair p2{"anni",5}
pait p3{root,false}
...
make_pair
auto mypair = make_pair("hello","boy");
auto youPair = make_pair("test","that");
.....
Tuple
tuple是pair的泛化,不仅包含两个类型的对象,当要把多个对象作为一个对象传递给函数时,tuple很有用:生成一个tuple对象使用:make_tuple
#include
auto my_tuple = make_tuple("name",42,"address",667,..);