C++中map容器提供一个键值对(key/value)容器,map与multimap差别仅仅在于multiple允许一个键对应多个值。对于迭代器来说,可以修改实值,而不能修改key。Map会根据key自动排序。
map 是键-值对的集合。map 类型通常可理解为关联数组:可使用键作为下标来获取一个值,正如内置数组类型一样。而关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置来获取。
定义与初始化
map<int,string> map1; //空map
函数名 | 意义 |
map<k, v>m | 创建一个名为m的空map对象,其键和值的类型分别为k和v |
map<k, v>m(m2) | 创建m2的副本m,m与m2必须有相同的键类型和值类型 |
map<k, v>m(b, e) | 创建map类型的对象m,存储迭代器b和e标记的范围内所有元素的副本。元素的类型必须能转换为pair<const k, v> |
在使用关联容器时,它的键不但有一个类型,而且还有一个相关的比较函数。所用的比较函数必须在键类型上定义严格弱排序(strict weak ordering):可理解为键类型数据上的“小于”关系,虽然实际上可以选择将比较函数设计得更复杂。
对于键类型,唯一的约束就是必须支持 < 操作符,至于是否支持其他的关系或相等运算,则不作要求。
常用的操作方法
添加元素有两种方法:1、先用下标操作符获取元素,然后给获取的元素赋值 2、使用insert成员函数实现
下标操作添加元素:如果该键已在容器中,则 map 的下标运算与 vector 的下标运算行为相同:返回该键所关联的值。只有在所查找的键不存在时,map 容器才为该键创建一个新的元素,并将它插入到此 map 对象中。此时,所关联的值采用值初始化:类类型的元素用默认构造函数初始化,而内置类型的元素初始化为 0。
1.insert 操作:
函数名 | 意义 |
m.insert(e) | e是一个用在m上的value_type 类型的值。如果键(e.first不在m中,则插入一个值为e.second 的新元素;如果该键在m中已存在,则保持m不变。该函数返回一个pair类型对象,包含指向键为e.first的元素的map迭代器,以及一个 bool 类型的对象,表示是否插入了该元素 |
m.insert(beg,end) | beg和end是标记元素范围的迭代器,其中的元素必须为m.value_type 类型的键-值对。对于该范围内的所有元素,如果它的键在 m 中不存在,则将该键及其关联的值插入到 m。返回 void 类型 |
m.insert(iter,e) | e是一个用在m上的 value_type 类型的值。如果键(e.first)不在m中,则创建新元素,并以迭代器iter为起点搜索新元素存储的位置。返回一个迭代器,指向m中具有给定键的元素 |
2.遍历
map中使用下标存在一个很危险的副作用:如果该键不在 map 容器中,那么下标操作会插入一个具有该键的新元素。所以map 容器提供了两个操作:count 和 find,用于检查某个键是否存在而不会插入该键。
函数名 | 意义 |
m.count(k) | 返回 m 中 k 的出现次数 |
m.find(k) | 如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。如果不存在,则返回超出末端迭代器。
|
3.删除
函数名 | 意义 |
m.erase(k) | 删除m中键为k的元素。返回size_type类型的值,表示删除的元素个数 |
m.erase(p) | 从m中删除迭代器p所指向的元素。p必须指向m中确实存在的元素,而且不能等于m.end()。返回void |
m.erase(b,e) | 从m中删除一段范围内的元素,该范围由迭代器对b和e标记。b和e必须标记m中的一段有效范围:即b和e都必须指向m中的元素或最后一个元素的下一个位置。而且,b和e要么相等(此时删除的范围为空),要么b所指向的元素必须出在e所 指向的元素之前。返回 void 类型 |
4.其他操作
map1.empty(); //判断空
map1.clear(); //清空所有元素
跟其他容器一样 ,map也支持迭代器遍历,迭代器也包括key | value。
测试文件:内容包括创建map,插入<key , value>的多种方式,删除<key, value>,查找元素,遍历元素。
#include <iostream>
#include <map>
using namespace std;
void IsStuEmpty(map<int, string>& mp_stu)
{
/* 判断当前容器是否为空 */
if (mp_stu.empty())
{
cout<<" map now is empty"<<endl;
}
else
{
cout<<"map now size = "<<mp_stu.size()<<endl;
}
}
void ClearStuMap(map<int, string>& mp_stu)
{
/* 判断当前容器是否为空 */
if (!mp_stu.empty())
{
cout<<" now clear map"<<endl;
/* 清空所有元素 */
mp_stu.clear();
}
}
void PrintMapByIterator(map<int,string>& mp_stu)
{
int key;
string value;
map<int,string>::iterator iter_map = mp_stu.begin();
cout<<"key value"<<endl;
for(; iter_map != mp_stu.end(); iter_map++)
{
key = iter_map->first;
value = iter_map->second;
cout<<key<<" "<<value<<endl;
}
}
template <class T1, class T2>
void InsertMap(T1 &key, T2 &value, std::map<T1, T2> &stu_map)
{
pair<int, string> pair_map(key, value);
stu_map.insert(pair_map);
}
int main()
{
map<int, string> mp_stu;/* 空map */
map<int,string>::iterator iter_Stu;
mp_stu[0] = "lily";/* 添加元素 */
/* 根据map 数据类型中的 value _type 插入 */
mp_stu.insert(map<int, string>::value_type(1, "lsh"));
IsStuEmpty(mp_stu);
pair<map<int, string>::iterator, bool> Insert_ret;
/* ret存储insert函数返回的pair对象。该pair的first成员是一个map迭代器,指向插入的键。
ret.first从insert返回的pair对象中获取 map 迭代器;ret.second从insert返回是否插入了该元素。*/
/* 根据pair构造插入 */
Insert_ret = mp_stu.insert(pair<int, string>(3,"lucky"));
cout<<"try insert key = "<<3<<"value = "<<" luckey Is "<<(Insert_ret.second >0 ? "OK":"Failed")<<endl;
Insert_ret = mp_stu.insert(make_pair<int, string>(4,"daived"));
cout<<"try insert key = "<<4<<"value = "<<" daived Is "<<(Insert_ret.second >0 ? "OK":"Failed")<<endl;
/* 根据key 获得value */
string va_key = mp_stu[3];
cout<<"map[3] = "<<va_key<<endl;
/* 根据迭代器遍历map 容器 */
PrintMapByIterator(mp_stu);
IsStuEmpty(mp_stu);
ClearStuMap(mp_stu);
IsStuEmpty(mp_stu);
for(int i= 4; i >=0; i--)
{
cout<<"erase ["<<i<<"] "<<(mp_stu.erase(i) >0 ? "OK":"Not Exist")<<endl;
}
IsStuEmpty(mp_stu);
/* 通过pair对象插入 */
pair<int, string> pair_stu(5, "stefan");
Insert_ret = mp_stu.insert(pair_stu);
cout<<"try insert key = "<<pair_stu.first<<"value = "<<pair_stu.second<<(Insert_ret.second >0 ? "OK":"Failed")<<endl;
pair<int, string>mkp_stu = make_pair<int, string>(6, "daimon");
Insert_ret = mp_stu.insert(mkp_stu);
cout<<"try insert key = "<<mkp_stu.first<<"value = "<<mkp_stu.second<<(Insert_ret.second >0 ? "OK":"Failed")<<endl;
PrintMapByIterator(mp_stu);
IsStuEmpty(mp_stu);
/* 通过模板函数插入 */
int key = 1;
string value("lily");
InsertMap(key, value, mp_stu);
iter_Stu = mp_stu.find(key); /* m.count(k) 返回 m 中 k 的出现次数 */
/* m.find(k) 如果m容器中存在按k索引的元素,则返回指向该元素的迭代器。
如果不存在,则返回超出末端迭代器。
*/
if (iter_Stu != mp_stu.end())
{
cout<<"insert map by template success, key = "<<iter_Stu->first<<" value = "<<iter_Stu->second<<endl;
}
PrintMapByIterator(mp_stu);
return 0;
}
注意:
使用map时要注意,在使用结构体而非标准数据类型作为 key值得时候,可能会出现编译错误,这是因为编译器无法比较两个结构体的大小,需要重载小于" < "运算符。
参考:https://blog.csdn.net/u014465639/article/details/70241850