一. 介绍
map的介绍
map是标准的关联式容器,一个map是一个键值对序列,即(key,value)对
它提供基于key的快速检索能力
map中key值是唯一的,字典中的元素按一定的顺序排列
map可以直接存取key所对应的value,支持[]操作符,如map[key]=value(将key键所对应的值修改为value
multimap与map的区别:map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。
特点
map<T1, T2> map_name; 这里的容器是键值对类型, 类似python的字典
二. 常用函数
1. 默认构造
①. map语法
map<键的类型, 值的类型> 容器名;
②. multimap语法
multimap<键的类型, 值的类型> 容器名;
注 :
其中键和值的类型还可以用各种指针类型或自定义类型
2. map容器的构造并初始化
map元素的插入 三种方式 :
● 通过pair插入对象:mapStu.insert(pair(键,值) );
● 通过value_type插入对象:mapStu.insert(map<int,string>::value_type(键,值) );
● 类似下标索引插入值:mapStu[键] = 值;
①. 使用pair进行insert构造
语法 : map.insert(…); //往容器插入元素,返回pair
map<int, string> mStu;//构建一个map
//错误示范
mStu.insert(pair(3,"nihao"))//错误, 在pair的初始化是,需要标志参数
//先构造再传入
pair<int, string> p (3, "nihao")
mStu.insert(p);
//直接传入, 成功的插入
mStu.insert(pair<int, string>(6, "good"));//正确
④. 通过emplace插入元素
//语法 : 字典名.emplace(键, 值);
map<int, string> mStu;
// 使用 emplace 插入新元素
mStu.emplace(1, "A"); // 插入键值对 {1, "A"}
mStu.emplace(2, "B"); // 插入键值对 {2, "B"}
// 替换已存在的键值对
mStu.emplace(1, "C"); // 不会替换,因为键值 1 已经存在
cout << mStu[1]; // 输出 "A"
③. 通过value_type的方式插入对象
//语法 :
mStu.insert(map<键类型, 值类型>::value_type(键, 值));
//直接初始化value并赋值
mStu.insert(map<int, string>::value_type(5, "hello"));
//先构建value_type 再传入
map<int, string>::value_type v (7, "你好");
mStu.insert(v)
④. 通过数组赋值的方法插入对象
//语法 :
map名字[键名称] = value; // 相当于中括号进行重载了 , 特点会进行覆盖
//例 :
mStu.insert(pair<int, string>(6, "good")); //已经插入对象
mStu.insert(pair<int, string>(6, "bad")); //此处的bad插入失败, 6的值不会被覆盖, 而且会返回一个迭代器指向已存在的元素
mStu[6] = "bad"; //此处把6的值覆盖成了bad
特点 :
map名字[键] = 值, 作为左值可以改变键对应的值
作为右值可以查找字典中键对应的值
注 : 如果查找的键不存在, 则会自动创建一个键值对, 其中值默认为 ’ ’
例 :
string stu_name = mStu[10];//综上没有10这个键, 这里创建了一个
cout << stu_name << endl; //此处输出一个 ' ' , 空字符
总结 : 方法③直观,但存在性能的问题 : 如果键存在则修改,如果不存在则插入
3. 与map的大小有关的函数
①. size()
语法 :
字典名.size(); // 返回元素的个数
②. empty()
语法:
字典名.empty(); // 判断字典容器是否为空, 是则返回1. 否则返回0
(常用 : !map.empty())
4. map中元素的删除
①. clear() (清空)
语法 :
字典名.clear() //删除所有元素
②. erase() (有返回值删除)
语法1 :
字典名.erase(左迭代器,右迭代器); //删除区间[左迭代器,右迭代器)的所有元素, 返回end()的迭代器
语法2 :
字典名.erase(迭代器); // 删除迭代器所指向的元素, 删除后返回下一个元素的迭代器
语法3 :
字典名.erase(键); // 删除字典容器中key对应的键值对, 删除成功后返回删除元素的个数,如果有多个则删除所有键值对等于给定键的键值对
注 :
如果是map则是1, 在multimap中可能会返回大于1的值
5. map中元素的排序规则
默认情况 , map 中元素的排序规则是以升序方式进行排列的, 所以键值小的元素会排在前面
但multimap中的键可以重复, 不一定可以按照特定顺序
6. map中元素的查找
①. find()
语法 : 字典名.find(; )// 成功返回对应查找到的迭代器,迭代器是指向pair, 可以通过解引用后用’.', 或者**直接用迭代器->**访问迭代器指向的pair中的键值对
, 失败则返回迭代器字典名.end()
②. at()
语法 : 字典名.(); // 成功返回传入键对应的值, 如果键值不存在就抛出out of range异常
注 : 常用find()代替, 通过
if (p.second != mStu.end())
cout << "euqle_range: first:" << p.first->first << " second:" << (p.second--)->second << endl;
else cout << "key not found" << endl;
③. count()
语法: 字典名.count(); // 返回容器中key为keyElem的对组个数
④. lower_bound()
语法 : 字典名.lower_bound(elem); //返回第一个>=elem元素的迭代器
⑤. upper_bound()
语法 : 字典名.upper_bound(elem); // 返回第一个>elem元素的迭代器
⑥. equal_range()
语法 : 字典名.equal_range(elem); //返回容器中与elem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end), 注意返回的是两个迭代器, 但是封装在一个pair中,所以①. auto, ②. 一个pair中两个map的迭代器类型
例 :
#include <iostream>
#include <map>
using namespace std;
int main()
{
map<int, string> mStu;
//插入 1-6
mStu.emplace(1, "good");
pair<int, string> p1(2, "bad");
mStu.insert(p1);
mStu.insert(pair<int, string>(3, "python"));
mStu[4] = "hello";
map<int, string>::value_type v1(5, "c");
mStu.insert(v1);
mStu.insert(map<int, string>::value_type(6, "people"));
//查找1-6
map<int, string>::iterator it1 = mStu.find(1);//注意返回的是迭代器,迭代器指向的是pair,piar中存放的是一个key一个value(要么解引用后用'.', 要么直接用迭代器->)
string name2 = mStu.at(2);//at只返回查到键对应的值
int n = mStu.count(3);//返回存在键为3的对组数, 在map中可以作为检测存在的函数, 在mlutimap中查找存在得个数
map<int, string>::iterator it2 = mStu.lower_bound(4);//第一个大于等于的迭代器, 在这则返回指向4的迭代器
map<int, string>::iterator it3 = mStu.upper_bound(5);//第一个大于的迭代器, 在这里则返回指向6的迭代器
pair<map<int, string>::iterator, map<int, string>::iterator> p = mStu.equal_range(6);//返回的pair中存放的是两个迭代器, beg和end, 所以pair<>尖括号中的类型是两个map的迭代器
//巧的是,此处返回的值6和6后面的元素的迭代器
//string name3 = mStu.at(7);//不存在则报错
//perror("at");
cout << "find(1):" << "second : " << it1->second << "first : " <<it1->first<< endl;//first是键, seconds是值
cout << "at(2): :" << name2 << endl;
cout << "count(3) : " << n << endl;
cout << "lower_bound: " << it2->second <<"first : " << it2->first << endl;//这里可以看出两个东西指向的位置是哪
cout << "upper_bound: " << it3->second << "first : " <<it3->first<< endl;
cout << "euqle_range: first:" << p.first->first << " second:" << (--p.second)->second << endl;//equal_range 函数返回值是一个 pair 对象,其中的 first 和 second 成员都是迭代器,分别指向所匹配键范围的起始位置和结束位置
//让second像前移一位,指向和beg相同的位置
if (p.second != mStu.end()) {
cout << "euqle_range: first:" << p.first->first << " second:" << (p.second--)->second << endl;
}
else {
cout << "key not found" << endl;//此时显示了这句话
}
return 0;
}
7. map中的交换函数
语法 :
字典名.swap(mp); //交换两个集合容器
例 :
//使用上面的字典
map<int, string> m1;
m1.insert(map<int,string>::value_type (0, "nan"));
mStu.swap(m1);//通过监视看到, 此时m1大小为6个元素, mStu大小为一个元素, 交换完成