文章目录
- Part.I Attention
- Chap.I 注意事项
- Chap.II 操作技巧
- Part.II Funciton
- Part.III Code
- Chap.I map
- Chap.II unordered_map
- Chap.III multimap
Part.I Attention
C++ 中 map 提供的是一种键值对容器,里面的数据都是成对出现的,每一对中的第一个值称之为关键字(key),每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值(Value)。
Chap.I 注意事项
使用map
需要注意的地方:
- 加引用
#include <map>
- 头文件
map
中除了有map
,还有multimap
;另外头文件unordered_map
中也有相似的容器unordered_map, unordered_multimap
,它们之间的区别如下:
名称 | 含义 |
---|---|
map | 在map中,键值key通常用于唯一的标识元素,而值value中存储与此键值key关联的内容;键值key和value的类型可能不同,并且在map的内部,key与value通过成员类型value_type绑定在一起,为其取别名为pair ;map中的key是唯一的,并且不能修改,遇到重复的key就会插入失败;但可以利用operator[] 对value进行修改;map的底层实现为红黑树,查找效率比较高,是O(logN) ; |
multimap | 与map的区别在于:multimap中的key可以重复;multimap中没有重载operator[] 功能;对于重复的元素,查找的时候也是返回中序遍历的第一个元素。 |
unordered_map | 存储键值对 <key, value> 类型的元素,其中各个键值对键的值不允许重复,且该容器中存储的键值对是无序的。 |
unordered_multimap | 和 unordered_map 唯一的区别在于,该容器允许存储多个键相同的键值对。 |
- 最基本的构造函数示例:
std::map<int, std::string> mapPerson;
map
中的元素是按照一定顺序存储的,默认是按键(key)升序排列的;
map<T1, T2> m; //默认按键的升序方式排列元素,相当于 map<T1, T2, less<T1>> m
map<T1, T2, less<T1>> m; //该容器是按键的升序方式排列元素。
map<T1, T2, greater<T1>> m; //该容器是按键的降序方式排列元素。
Chap.II 操作技巧
下面是一些操作示例:
// 用insert函數插入pair
mapStudent.insert(make_pair(000, "student_zero"));
// 用insert函數插入pair
mapStudent.insert({000, "student_zero"});
// 用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));
// 用"array"方式插入
mapStudent[123] = "student_first";
// 查找元素,没找到就返回 end
mapStudent.find("123")!=mapStudent.end()
// 根据键值删除元素,如果删除成功返回1,否则返回0
mapStudent.erase("123");
// 清空整个 map
mapStudent.erase(mapStudent.begin(), mapStudent.end());
Part.II Funciton
这里仅仅介绍map
的函数(其他三种map的函数和它大差不差,有些少一些函数或者多那么几个函数),如下图:
函数 | 含义 |
---|---|
begin() | 返回指向 map 头部的迭代器(注意是排好序的) |
clear() | 删除所有元素 |
count(key) | 返回键key 出现的次数,map 中此函数返回的最大值为1 |
empty() | 如果 map 为空则返回 true |
emplace() | 在当前 map 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。 |
end() | 返回指向 map 末尾的迭代器,注意它可不是最后一个元素,而是容器的末尾,类似于char[] 类型中的'\0' |
equal_range() | 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对(map 容器键值对唯一,因此该范围最多包含一个键值对)。 |
erase() | 删除 map 容器指定位置、指定键(key)值或者指定区域内的键值对。 |
find(key) | 在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。 |
get_allocator() | 返回map的配置器,比如map<string, int>::allocator_type |
insert() | 插入元素 |
key_comp() | 返回比较元素key的函数 |
lower_bound(key) | 返回一个指向当前 map 容器中第一个大于或等于 key 的键值对的双向迭代器 |
max_size() | 返回可以容纳的最大元素个数 |
rbegin() | 返回一个指向map尾部的逆向迭代器 |
rend() | 返回一个指向map头部的逆向迭代器 |
size() | 返回map中元素的个数 |
swap() | 交换两个map |
upper_bound(key) | 返回一个指向当前 map 容器中第一个大于 key 的键值对的迭代器。 |
value_comp() | 返回比较元素 value 的函数 |
Part.III Code
Chap.I map
测试代码如下:
#include <iostream>
#include <iomanip>
#include <map>
using namespace std;
int main()
{
map<string,int> data {{"Tom",10},{"Jerry",20}};
// map<string,int> data {make_pair("Tom",10),make_pair("Jerry",20)} // the same as above
auto tmp=data.begin();
cout<< tmp->first << " " << tmp->second<<endl;
data["Allice"]=30;
data.insert({"Tony",10});
cout<<data["Tony"] << endl;
data.insert({"Tony",20}); // it can't work, data["Tony"]=20; is OK!
cout<<data["Tony"] << endl;
tmp=data.begin();
cout<< tmp->first << " " << tmp->second<<endl;
cout<<data.size() << setw(15)<<data.max_size()<<endl;
for(auto itr=data.rbegin();itr!=data.rend();itr++)
cout<< itr->first<<" " <<itr->second<< endl;
getchar();
return 0;
}
输出如下:
Jerry 20
10
10
Allice 30
4 97612893
Tony 10
Tom 10
Jerry 20
Allice 30
Chap.II unordered_map
测试代码如下:
#include <iostream>
#include <iomanip>
#include <unordered_map>
using namespace std;
int main()
{
unordered_map<string,int> data {{"Tom",10},{"Jerry",20}};
// map<string,int> data {make_pair("Tom",10),make_pair("Jerry",20)} // the same as above
auto tmp=data.begin();
cout<< tmp->first << " " << tmp->second<<endl;
data["Allice"]=30;
data.insert({"Tony",10});
cout<<data["Tony"] << endl;
data.insert({"Tony",20}); // it can't work, data["Tony"]=20; is OK!
cout<<data["Tony"] << endl;
tmp=data.begin();
cout<< tmp->first << " " << tmp->second<<endl;
cout<<data.size() << setw(15)<<data.max_size()<<endl;
for(auto itr=data.begin();itr!=data.end();itr++)
cout<< itr->first<<" " <<itr->second<< endl;
getchar();
return 0;
}
输出如下:
Jerry 20
10
10
Tony 10
4 119304647
Tony 10
Allice 30
Jerry 20
Tom 10
Chap.III multimap
测试代码如下:
#include <iostream>
#include <iomanip>
#include <map>
using namespace std;
int main()
{
multimap<string,int> data {{"Tom",10},{"Jerry",20}};
// map<string,int> data {make_pair("Tom",10),make_pair("Jerry",20)} // the same as above
auto tmp=data.begin();
cout<< tmp->first << " " << tmp->second<<endl;
data.insert({"Allice",30});
data.insert({"Tony",10});
auto ret=data.equal_range("Tony");
for(auto itr=ret.first;itr!=ret.second;itr++)
cout<<itr->second<< " ";
cout << endl;
data.insert({"Tony",20}); // it work! data["Tony"]=20; is Error!
ret=data.equal_range("Tony");
for(auto itr=ret.first;itr!=ret.second;itr++)
cout<<itr->second<< " ";
cout << endl;
tmp=data.begin();
cout<< tmp->first << " " << tmp->second<<endl;
cout<<data.size() << setw(15)<<data.max_size()<<endl;
for(auto itr=data.begin();itr!=data.end();itr++)
cout<< itr->first<<" " <<itr->second<< endl;
getchar();
return 0;
}
输出如下:
Jerry 20
10
10 20
Allice 30
5 97612893
Allice 30
Jerry 20
Tom 10
Tony 10
Tony 20