1. 简介
map是一种关联式容器,包含唯一的键值对,即 (key, value),内部会根据key值进行排序;增加、修改和查询具有对数的时间复杂度,其存储结构为红黑树;
头文件和定义
//头文件
#include <map>
//定义
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T>>
> class map;
2. 初始化
map的初始化方法如下所示
/*
* @brief map
* g++ -g map_main.cc -o d -std=c++11
*
*/
#include <iostream>
#include <map>
#include <iterator>
#include <string>
#include <algorithm>
template<typename T>
void showInfo(T &t)
{
auto iter = t.begin();
while (iter != t.end())
{
std::cout<<iter->first<<" "<<iter->second<<std::endl;
iter++;
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::map<int32_t, std::string> m1;
m1.insert({2,"c"});
m1.insert({4,"c++"});
m1.insert({5,"python"});
showInfo(m1);
std::map<int32_t, std::string> m2{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
showInfo(m2);
std::map<int32_t, std::string> m3;
m3.insert(std::pair<int32_t, std::string>(2,"windows")); //pair
m3.insert(std::pair<int32_t, std::string>(3,"linux"));
m3.insert(std::make_pair(1,"mac")); //make_pair
m3.insert(std::make_pair(5,"unix")); //
showInfo(m3);
std::map<int32_t, std::string> m4 = m1;
showInfo(m4);
m4[10] = "shell"; //元素的添加
m4[7] = "Rust";
m4[5] = "Java"; //会替换(5, python)
showInfo(m4);
return 0;
}
输出
2 c
4 c++
5 python
1 student
2 girl
3 boy
4 teacher
1 mac
2 windows
3 linux
5 unix
2 c
4 c++
5 python
2 c
4 c++
5 Java
7 Rust
10 shell
3. 使用
3.1 元素访问
方法 | 说明 |
---|---|
at() | 元素访问 |
operator[] | 元素访问 |
iterator | 可以访问元素,也可以遍历字典中的元素 |
示例
int main(int argc, char *argv[])
{
//元素访问
std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
std::cout<<"m1[2] value is: "<<m1.at(1)<<std::endl; //at 越界会抛出异常
std::cout<<"m1[1] value is: "<<m1[1]<<"\n\n"; //[] 不会抛出异常
auto iter = m1.begin();
std::cout<<"iter->first value is: "<<iter->first<<"\n"; //迭代器输出key值
std::cout<<"iter->second value is: "<<iter->second<<"\n"; //迭代器输出value值
return 0;
}
输出
m1[2] value is: student
m1[1] value is: student
iter->first value is: 1
iter->second value is: student
3.2 元素的大小
方法 | 说明 |
---|---|
empty | 数组判空 |
size | 字典大小 |
max_size | 最大容量 |
clear | 清空map的大小 |
swap | 交换两个map的内容 |
示例
template<typename T>
void showInfo(T &t)
{
auto iter = t.begin();
while (iter != t.end())
{
std::cout<<"["<<iter->first<<", "<<iter->second<<"]; ";
iter++;
}
std::cout<<std::endl;
}
int main(int argc, char *argv[])
{
std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
std::cout<<"size value is: "<<m1.size()<<"\n";
std::cout<<"max_size value is: "<<m1.max_size()<<"\n\n";
std::map<int32_t, std::string> m2{{2,"c++"},{1, "c"}};
m1.swap(m2);
showInfo(m1);
showInfo(m2);
m1.clear();
if(m1.empty())
{
std::cout<<"m1 empty"<<"\n";
}
else{
std::cout<<"m1 not empty"<<"\n";
}
return 0;
}
结果
size value is: 4
max_size value is: 256204778801521550
[1, c]; [2, c++];
[1, student]; [2, girl]; [3, boy]; [4, teacher];
m1 empty
3.3 元素的修改
主要包括元素的赋值、插入和删除等
方法 | 说明 |
---|---|
= | 直接赋值 |
get_allocator | 返回内存分配器 |
insert | 插入元素 |
emplace | 插入元素 |
emplace_hint | 插入元素,需要写位置 |
tyr_emplace(C++17) | 插入元素 |
erase | 删除元素 |
extract(C++17) | 元素的删除,可以返回该值 |
merge(C++17) | map的合并 |
示例
int main(int argc, char *argv[])
{
std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
std::map<int32_t, std::string> m2{{2,"c++"},{1, "c"}};
//1.元素插入
m2.insert(std::make_pair(5,"linux"));
m2.emplace(std::make_pair(7,"python"));
m2.emplace_hint(m2.end(),std::make_pair(9,"golang")); //本来就是自动排序
m2.try_emplace(10,"Rust");
showInfo(m2);
//2.元素删除
m2.erase(10); //根据key值进行删除
m2.erase(m2.begin()); //根据迭代器删除
showInfo(m2);
//3.extract
m2.extract(m2.begin());
showInfo(m2);
std::cout<<std::endl;
//4.merge
m2.merge(m1); //合并之后,m1是空的
showInfo(m1);
showInfo(m2);
return 0;
}
结果
[1, c]; [2, c++]; [5, linux]; [7, python]; [9, golang]; [10, Rust];
[2, c++]; [5, linux]; [7, python]; [9, golang];
[5, linux]; [7, python]; [9, golang];
[1, student]; [2, girl]; [3, boy]; [4, teacher]; [5, linux]; [7, python]; [9, golang];
3.4 元素的操作
方法 | 说明 |
---|---|
count | 计算map中元素出现的次数 |
find | 查找元素 |
equal_range | 返回的是一个范围 [lower_bound, upper_bound] |
lower_bound | 返回当前元素的位置,查找不到返回end |
upper_bound | 返回当前元素的下一个位置,查找不到返回end |
key_comp | 比较函数,key比较 |
value_comp | 比较函数,元素比较 |
示例
int main(int argc, char *argv[])
{
//1.count find
std::map<int32_t, std::string> m1{{1,"student"},{4,"teacher"},{3,"boy"},{2,"girl"}};
std::cout<<"[count]\n";
std::cout<<m1.count(1)<<std::endl;
auto au = m1.find(2);
if(au == m1.end())
{
std::cout<<"not find"<<std::endl;
}
else{
std::cout<<"find. the value is: "<<au->second<<std::endl;
}
//2. equal_range
auto iter_equal = m1.equal_range(3);
std::cout<<iter_equal.first->second<<std::endl;
std::cout<<iter_equal.second->second<<std::endl; //输出tearch
//3. lower_bound upper_bound
auto iter_lower = m1.lower_bound(3);
std::cout<<iter_lower->second<<std::endl;
auto iter_upper = m1.upper_bound(3);
std::cout<<iter_upper->second<<std::endl; //输出tearch
//4. key_comp
auto keyComp = m1.key_comp();
for(auto au : m1)
{
if(keyComp(au.first, 2))
{
std::cout<<"true"<<" ";
}
else{
std::cout<<"false"<<" ";
}
}
std::cout<<std::endl<<std::endl;
//5. value_comp
auto valueComp = m1.value_comp();
const std::pair<int, std::string> val = { 100, "a" };
for(auto au : m1)
{
if(valueComp(au, val))
{
std::cout<<"true"<<" ";
}
else{
std::cout<<"false"<<" ";
}
}
std::cout<<std::endl;
return 0;
}
输出
[count]
1
find. the value is: girl
boy
teacher
boy
teacher
true false false false
true true true true
3.5 迭代器
迭代器最好结合STL中的算法一起使用;迭代器的返回值最好用auto接收;
map的元素是pair,注意在访问元素的时候有first和second;
迭代器的类型包括:iterator、const_iterator、reverse_iterator和const_reverse_iterator
方法 | 说明 |
---|---|
begin | 返回map的头元素(迭代器),其值可修改 |
end | 返回map的尾元素(迭代器),其值可修改 |
cbegin | 返回map的头元素(迭代器),其值不可修改,const属性 |
cend | 返回map的尾元素(迭代器),其值不可修改,const属性 |
rbegin | 反序返回map的头元素(迭代器),其值可修改,同end() |
rend | 反序返回map的尾元素(迭代器),其值可修改,同begin() |
crbegin | 反序返回map的头元素(迭代器),其值不可修改,同cend,const属性 |
crend | 反序返回map的头元素(迭代器),其值不可修改,同cbegin,const属性 |
迭代器的辅助函数
辅助函数的使用需要包含头文件
#include <iterator>
方法 | 说明 |
---|---|
advance | 移动迭代器的位置 |
distance | 计算两个迭代器的距离 |
begin | 返回容器第一个元素的迭代器 |
end | 返回容器最后一个元素的迭代器 |
prev | 迭代器向前移动一个元素 |
next | 迭代器向后移动一个元素 |