map容器
map 容器存储的都是 pair 对象,也就是用 pair 类模板创建的键值对。其中,各个键值对的键和值可以是任意数据类型,包括 C++ 基本数据类型(int、double 等)、使用结构体或类自定义的类型。
通常情况下,map 容器中存储的各个键值对都选用 string 字符串作为键的类型。在使用 map 容器存储多个键值对时,该容器会自动根据各键值对的键的大小,按照既定的规则进行排序。
默认情况下,map 容器选用std::less<T>
排序规则(其中 T 表示键的数据类型),其会根据键的大小对所有键值对做升序排序。当然,根据实际情况的需要,我们可以手动指定 map 容器的排序规则,既可以选用 STL 标准库中提供的其它排序规则(比如std::greater<T>
),也可以自定义排序规则。
使用 map 容器存储的各个键值对,键的值既不能重复也不能被修改。换句话说,map 容器中存储的各个键值对不仅键的值独一无二,键的类型也会用 const 修饰。
创建map容器的几种方法
-
通过调用 map 容器类的默认构造函数,可以创建出一个空的 map 容器:
std::map<std::string, int>myMap;
-
在创建 map 容器的同时,也可以进行初始化:
std::map<std::string, int>myMap{ {"C语言教程",10},{"STL教程",20} }; std::map<std::string, int>myMap{std::make_pair("C语言教程",10),std::make_pair("STL教程",20)};
-
利用先前已创建好的 map 容器,再创建一个新的 map 容器:
std::map<std::string, int>newMap(myMap);
当有临时的 map 对象作为参数,传递给要初始化的 map 容器时,此时就会调用移动构造函数
#创建一个会返回临时 map 对象的函数 std::map<std::string,int> disMap() { std::map<std::string, int>tempMap{ {"C语言教程",10},{"STL教程",20} }; return tempMap; } //调用 map 类模板的移动构造函数创建 newMap 容器 std::map<std::string, int>newMap(disMap());
-
取已建 map 容器中指定区域内的键值对,创建并初始化新的 map 容器
std::map<std::string, int>myMap{ {"C语言教程",10},{"STL教程",20} }; std::map<std::string, int>newMap(++myMap.begin(), myMap.end());
-
手动修改了 myMap 容器的排序规则,令其作降序排序
std::map<std::string, int, std::greater<std::string> >myMap{ {"C语言教程",10},{"STL教程",20} };
C++ map容器的成员方法
成员方法 | 功能 |
---|---|
begin() | 返回指向容器中第一个(注意,是已排好序的第一个)键值对的双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
end() | 返回指向容器最后一个元素(注意,是已排好序的最后一个)所在位置后一个位置的双向迭代器,通常和 begin() 结合使用。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
rbegin() | 返回指向最后一个(注意,是已排好序的最后一个)元素的反向双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
rend() | 返回指向第一个(注意,是已排好序的第一个)元素所在位置前一个位置的反向双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
cbegin() | 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
cend() | 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
crbegin() | 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
crend() | 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
find(key) | 在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
lower_bound(key) | 返回一个指向当前 map 容器中第一个大于或等于 key 的键值对的双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
upper_bound(key) | 返回一个指向当前 map 容器中第一个大于 key 的键值对的迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
equal_range(key) | 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对(map 容器键值对唯一,因此该范围最多包含一个键值对)。 |
empty() | 若容器为空,则返回 true;否则 false。 |
size() | 返回当前 map 容器中存有键值对的个数。 |
max_size() | 返回 map 容器所能容纳键值对的最大个数,不同的操作系统,其返回值亦不相同。 |
operator[] | map容器重载了 [] 运算符,只要知道 map 容器中某个键值对的键的值,就可以向获取数组中元素那样,通过键直接获取对应的值。 |
at(key) | 找到 map 容器中 key 键对应的值,如果找不到,该函数会引发 out_of_range 异常。 |
insert() | 向 map 容器中插入键值对。 |
erase() | 删除 map 容器指定位置、指定键(key)值或者指定区域内的键值对。后续章节还会对该方法做重点讲解。 |
swap() | 交换 2 个 map 容器中存储的键值对,这意味着,操作的 2 个键值对的类型必须相同。 |
clear() | 清空 map 容器中所有的键值对,即使 map 容器的 size() 为 0。 |
emplace() | 在当前 map 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。 |
emplace_hint() | 在本质上和 emplace() 在 map 容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数。 |
count(key) | 在当前 map 容器中,查找键为 key 的键值对的个数并返回。注意,由于 map 容器中各键值对的键的值是唯一的,因此该函数的返回值最大为 1。 |
#include <iostream>
#include <map> // map
#include <string> // string
using namespace std;
int main() {
//创建空 map 容器,默认根据个键值对中键的值,对键值对做降序排序
std::map<std::string, std::string, std::greater<std::string>>myMap;
//调用 emplace() 方法,直接向 myMap 容器中指定位置构造新键值对
myMap.emplace("C语言教程","http://c.biancheng.net/c/");
myMap.emplace("Python教程", "http://c.biancheng.net/python/");
myMap.emplace("STL教程", "http://c.biancheng.net/stl/");
//输出当前 myMap 容器存储键值对的个数
cout << "myMap size==" << myMap.size() << endl;
//判断当前 myMap 容器是否为空
if (!myMap.empty()) {
//借助 myMap 容器迭代器,将该容器的键值对逐个输出
for (auto i = myMap.begin(); i != myMap.end(); ++i) {
cout << i->first << " " << i->second << endl;
}
}
return 0;
}
map容器迭代器
C++ STL 标准库为 map 容器配备的是双向迭代器(bidirectional iterator)。这意味着,map 容器迭代器只能进行 ++p、p++、–p、p–、*p 操作,并且迭代器之间只能使用 == 或者 != 运算符进行比较。
以begin()/end()
组合为例,演示了如何遍历 map 容器:
#include <iostream>
#include <map> // pair
#include <string> // string
using namespace std;
int main() {
//创建并初始化 map 容器
std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"},{"C语言教程","http://c.biancheng.net/c/"} };
//调用 begin()/end() 组合,遍历 map 容器
for (auto iter = myMap.begin(); iter != myMap.end(); ++iter) {
cout << iter->first << " " << iter->second << endl;
}
return 0;
}
map 类模板中还提供了 find()
成员方法,它能帮我们查找指定 key 值的键值对,如果成功找到,则返回一个指向该键值对的双向迭代器;反之,其功能和 end() 方法相同。
#include <iostream>
#include <map> // pair
#include <string> // string
using namespace std;
int main() {
//创建并初始化 map 容器
std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"},
{"C语言教程","http://c.biancheng.net/c/"},
{"Java教程","http://c.biancheng.net/java/"} };
//查找键为 "Java教程" 的键值对
auto iter = myMap.find("Java教程");
//从 iter 开始,遍历 map 容器
for (; iter != myMap.end(); ++iter) {
cout << iter->first << " " << iter->second << endl;
}
return 0;
}
map 类模板中还提供有lower_bound(key)
和upper_bound(key)
成员方法,它们的功能是类似的,唯一的区别在于:
- lower_bound(key) 返回的是指向第一个键不小于 key 的键值对的迭代器;
- upper_bound(key) 返回的是指向第一个键大于 key 的键值对的迭代器;
#include <iostream>
#include <map> // pair
#include <string> // string
using namespace std;
int main() {
//创建并初始化 map 容器
std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"},
{"C语言教程","http://c.biancheng.net/c/"},
{"Java教程","http://c.biancheng.net/java/"} };
//找到第一个键的值不小于 "Java教程" 的键值对
auto iter = myMap.lower_bound("Java教程");
cout << "lower:" << iter->first << " " << iter->second << endl;
//找到第一个键的值大于 "Java教程" 的键值对
iter = myMap.upper_bound("Java教程");
cout <<"upper:" << iter->first << " " << iter->second << endl;
return 0;
}
lower_bound(key) 和 upper_bound(key) 更多用于 multimap 容器,在 map 容器中很少用到。
equal_range(key)
成员方法可以看做是 lower_bound(key) 和 upper_bound(key) 的结合体,该方法会返回一个 pair 对象,其中的 2 个元素都是迭代器类型,其中 pair.first 实际上就是 lower_bound(key) 的返回值,而 pair.second 则等同于 upper_bound(key) 的返回值。
equal_range(key) 成员方法表示的一个范围,位于此范围中的键值对,其键的值都为 key
#include <iostream>
#include <utility> //pair
#include <map> // map
#include <string> // string
using namespace std;
int main() {
//创建并初始化 map 容器
std::map<string, string>myMap{ {"STL教程","http://c.biancheng.net/stl/"},
{"C语言教程","http://c.biancheng.net/c/"},
{"Java教程","http://c.biancheng.net/java/"} };
//创建一个 pair 对象,来接收 equal_range() 的返回值
pair <std::map<string, string>::iterator, std::map<string, string>::iterator> myPair = myMap.equal_range("C语言教程");
//通过遍历,输出 myPair 指定范围内的键值对
for (auto iter = myPair.first; iter != myPair.second; ++iter) {
cout << iter->first << " " << iter->second << endl;
}
return 0;
}
和 lower_bound(key)、upper_bound(key) 一样,该方法也更常用于 multimap 容器,因为 map 容器中各键值对的键的值都是唯一的,因此通过 map 容器调用此方法,其返回的范围内最多也只有 1 个键值对。
map获取键对应值的几种方法
-
map 类模板中对
[ ]
运算符进行了重载,通过指定的键,我们可以轻松获取 map 容器中该键对应的值。#include <iostream> #include <map> // map #include <string> // string using namespace std; int main() { //创建并初始化 map 容器 std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"}, {"C语言教程","http://c.biancheng.net/c/"}, {"Java教程","http://c.biancheng.net/java/"} }; string cValue = myMap["C语言教程"]; cout << cValue << endl; return 0; }
若当前 map 容器中没有包含该指定键的键值对,则此时使用 [ ] 运算符将不再是访问容器中的元素,而变成了向该 map 容器中增添一个键值对。
#include <iostream> #include <map> // map #include <string> // string using namespace std; int main() { //创建空 map 容器 std::map<std::string, int>myMap; int cValue = myMap["C语言教程"]; for (auto i = myMap.begin(); i != myMap.end(); ++i) { cout << i->first << " "<< i->second << endl; } return 0; }
-
使用 at() 成员方法,需要根据指定的键,才能从容器中找到该键对应的值;如果在当前容器中查找失败,该方法不会向容器中添加新的键值对,而是直接抛出 out_of_range 异常。
#include <iostream> #include <map> // map #include <string> // string using namespace std; int main() { //创建并初始化 map 容器 std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"}, {"C语言教程","http://c.biancheng.net/c/"}, {"Java教程","http://c.biancheng.net/java/"} }; cout << myMap.at("C语言教程") << endl; //下面一行代码会引发 out_of_range 异常 //cout << myMap.at("Python教程") << endl; return 0; }
-
借助 find() 成员方法间接实现此目的
#include <iostream> #include <map> // map #include <string> // string using namespace std; int main() { //创建并初始化 map 容器 std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"}, {"C语言教程","http://c.biancheng.net/c/"}, {"Java教程","http://c.biancheng.net/java/"} }; map< std::string, std::string >::iterator myIter = myMap.find("C语言教程"); cout << myIter->first << " " << myIter->second << endl; return 0; }
如果 find() 查找失败,会导致第 13 行代码运行出错。因为当 find() 方法查找失败时,其返回的迭代器指向的是容器中最后一个键值对之后的位置,即不指向任何有意义的键值对,也就没有所谓的 first 和 second 成员了。
-
遍历整个 map 容器,找到包含指定键的键值对,进而获取该键对应的值。
#include <iostream> #include <map> // map #include <string> // string using namespace std; int main() { //创建并初始化 map 容器 std::map<std::string, std::string>myMap{ {"STL教程","http://c.biancheng.net/stl/"}, {"C语言教程","http://c.biancheng.net/c/"}, {"Java教程","http://c.biancheng.net/java/"} }; for (auto iter = myMap.begin(); iter != myMap.end(); ++iter) { //调用 string 类的 compare() 方法,找到一个键和指定字符串相同的键值对 if (!iter->first.compare("C语言教程")) { cout << iter->first << " " << iter->second << endl; } } return 0; }
map insert()插入数据的4种方式
insert() 方法可以将新的键值对插入到 map 容器中的指定位置,但这与 map 容器会自动对存储的键值对进行排序并不冲突。当使用 insert() 方法向 map 容器的指定位置插入新键值对时,其底层会先将新键值对插入到容器的指定位置,如果其破坏了 map 容器的有序性,该容器会对新键值对的位置进行调整。
-
无需指定插入位置,直接将键值对添加到 map 容器中。
//1、引用传递一个键值对 pair<iterator,bool> insert (const value_type& val); //2、以右值引用的方式传递键值对 template <class P> pair<iterator,bool> insert (P&& val);
其中,val 参数表示键值对变量,同时该方法会返回一个 pair 对象,其中 pair.first 表示一个迭代器,pair.second 为一个 bool 类型变量:
- 如果成功插入 val,则该迭代器指向新插入的 val,bool 值为 true;
- 如果插入 val 失败,则表明当前 map 容器中存有和 val 的键相同的键值对(用 p 表示),此时返回的迭代器指向 p,bool 值为 false。
#include <iostream> #include <map> //map #include <string> //string using namespace std; int main() { //创建一个空 map 容器 std::map<string, string> mymap; //创建一个真实存在的键值对变量 std::pair<string, string> STL = { "STL教程","http://c.biancheng.net/stl/" }; //创建一个接收 insert() 方法返回值的 pair 对象 std::pair<std::map<string, string>::iterator, bool> ret; //插入 STL,由于 STL 并不是临时变量,因此会以第一种方式传参 ret = mymap.insert(STL); cout << "ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl; //以右值引用的方式传递临时的键值对变量 ret = mymap.insert({ "C语言教程","http://c.biancheng.net/c/" }); cout << "ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl; //插入失败样例 ret = mymap.insert({ "STL教程","http://c.biancheng.net/java/" }); cout << "ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl; return 0; }
-
insert() 方法还支持向 map 容器的指定位置插入新键值对
//以普通引用的方式传递 val 参数 iterator insert (const_iterator position, const value_type& val); //以右值引用的方式传递 val 键值对参数 template <class P> iterator insert (const_iterator position, P&& val);
其中 val 为要插入的键值对变量。注意,和第 1 种方式的语法格式不同,这里 insert() 方法返回的是迭代器,而不再是 pair 对象:
- 如果插入成功,insert() 方法会返回一个指向 map 容器中已插入键值对的迭代器;
- 如果插入失败,insert() 方法同样会返回一个迭代器,该迭代器指向 map 容器中和 val 具有相同键的那个键值对。
#include <iostream> #include <map> //map #include <string> //string using namespace std; int main() { //创建一个空 map 容器 std::map<string, string> mymap; //创建一个真实存在的键值对变量 std::pair<string, string> STL = { "STL教程","http://c.biancheng.net/stl/" }; //指定要插入的位置 std::map<string, string>::iterator it = mymap.begin(); //向 it 位置以普通引用的方式插入 STL auto iter1 = mymap.insert(it, STL); cout << iter1->first << " " << iter1->second << endl; //向 it 位置以右值引用的方式插入临时键值对 auto iter2 = mymap.insert(it, std::pair<string, string>("C语言教程", "http://c.biancheng.net/c/")); cout << iter2->first << " " << iter2->second << endl; //插入失败样例 auto iter3 = mymap.insert(it, std::pair<string, string>("STL教程", "http://c.biancheng.net/java/")); cout << iter3->first << " " << iter3->second << endl; return 0; }
即便指定了新键值对的插入位置,map 容器仍会对存储的键值对进行排序。也可以说,决定新插入键值对位于 map 容器中位置的,不是 insert() 方法中传入的迭代器,而是新键值对中键的值。
-
支持向当前 map 容器中插入其它 map 容器指定区域内的所有键值对
template <class InputIterator> void insert (InputIterator first, InputIterator last);
其中 first 和 last 都是迭代器,它们的组合
<first,last>
可以表示某 map 容器中的指定区域。#include <iostream> #include <map> //map #include <string> //string using namespace std; int main() { //创建并初始化 map 容器 std::map<std::string, std::string>mymap{ {"STL教程","http://c.biancheng.net/stl/"}, {"C语言教程","http://c.biancheng.net/c/"}, {"Java教程","http://c.biancheng.net/java/"} }; //创建一个空 map 容器 std::map<std::string, std::string>copymap; //指定插入区域 std::map<string, string>::iterator first = ++mymap.begin(); std::map<string, string>::iterator last = mymap.end(); //将<first,last>区域内的键值对插入到 copymap 中 copymap.insert(first, last); //遍历输出 copymap 容器中的键值对 for (auto iter = copymap.begin(); iter != copymap.end(); ++iter) { cout << iter->first << " " << iter->second << endl; } return 0; }
-
insert() 方法还允许一次向 map 容器中插入多个键值对
void insert ({val1, val2, ...});
#include <iostream> #include <map> //map #include <string> //string using namespace std; int main() { //创建空的 map 容器 std::map<std::string, std::string>mymap; //向 mymap 容器中添加 3 个键值对 mymap.insert({ {"STL教程", "http://c.biancheng.net/stl/"}, { "C语言教程","http://c.biancheng.net/c/" }, { "Java教程","http://c.biancheng.net/java/" } }); for (auto iter = mymap.begin(); iter != mymap.end(); ++iter) { cout << iter->first << " " << iter->second << endl; } return 0; }
emplace()和emplace_hint()
实现相同的插入操作,无论是用 emplace() 还是 emplace_hont(),都比 insert() 方法的效率高.
emplace()
template <class... Args>
pair<iterator,bool> emplace (Args&&... args);
参数 (Args&&… args) 指的是,这里只需要将创建新键值对所需的数据作为参数直接传入即可,此方法可以自行利用这些数据构建出指定的键值对。另外,该方法的返回值也是一个 pair 对象,其中 pair.first 为一个迭代器,pair.second 为一个 bool 类型变量:
- 当该方法将键值对成功插入到 map 容器中时,其返回的迭代器指向该新插入的键值对,同时 bool 变量的值为 true;
- 当插入失败时,则表明 map 容器中存在具有相同键的键值对,此时返回的迭代器指向此具有相同键的键值对,同时 bool 变量的值为 false。
#include <iostream>
#include <map> //map
#include <string> //string
using namespace std;
int main()
{
//创建并初始化 map 容器
std::map<string, string>mymap;
//插入键值对
pair<map<string, string>::iterator, bool> ret = mymap.emplace("STL教程", "http://c.biancheng.net/stl/");
cout << "1、ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl;
//插入新键值对
ret = mymap.emplace("C语言教程", "http://c.biancheng.net/c/");
cout << "2、ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl;
//失败插入的样例
ret = mymap.emplace("STL教程", "http://c.biancheng.net/java/");
cout << "3、ret.iter = <{" << ret.first->first << ", " << ret.first->second << "}, " << ret.second << ">" << endl;
return 0;
}
emplace_hint()
template <class... Args>
iterator emplace_hint (const_iterator position, Args&&... args);
显然和 emplace() 语法格式相比,有以下 2 点不同:
- 该方法不仅要传入创建键值对所需要的数据,还需要传入一个迭代器作为第一个参数,指明要插入的位置(新键值对键会插入到该迭代器指向的键值对的前面);
- 该方法的返回值是一个迭代器,而不再是 pair 对象。当成功插入新键值对时,返回的迭代器指向新插入的键值对;反之,如果插入失败,则表明 map 容器中存有相同键的键值对,返回的迭代器就指向这个键值对。
#include <iostream>
#include <map> //map
#include <string> //string
using namespace std;
int main()
{
//创建并初始化 map 容器
std::map<string, string>mymap;
//指定在 map 容器插入键值对
map<string, string>::iterator iter = mymap.emplace_hint(mymap.begin(),"STL教程", "http://c.biancheng.net/stl/");
cout << iter->first << " " << iter->second << endl;
iter = mymap.emplace_hint(mymap.begin(), "C语言教程", "http://c.biancheng.net/c/");
cout << iter->first << " " << iter->second << endl;
//插入失败样例
iter = mymap.emplace_hint(mymap.begin(), "STL教程", "http://c.biancheng.net/java/");
cout << iter->first << " " << iter->second << endl;
return 0;
}
multimap容器
和 map 容器的区别在于,multimap 容器中可以同时存储多(≥2)个键相同的键值对。
实现 multimap 容器的类模板也定义在<map>
头文件,并位于 std 命名空间中。
创建multimap容器的方法
-
通过调用 multimap 类模板的默认构造函数,可以创建一个空的 multimap 容器:
std::multimap<std::string, std::string>mymultimap;
-
在创建 multimap 容器的同时,还可以进行初始化操作。
//创建并初始化 multimap 容器 multimap<string, string>mymultimap{ {"C语言教程", "http://c.biancheng.net/c/"}, {"Python教程", "http://c.biancheng.net/python/"}, {"STL教程", "http://c.biancheng.net/stl/"} }; //借助 pair 类模板的构造函数来生成各个pair类型的键值对 multimap<string, string>mymultimap{ pair<string,string>{"C语言教程", "http://c.biancheng.net/c/"}, pair<string,string>{ "Python教程", "http://c.biancheng.net/python/"}, pair<string,string>{ "STL教程", "http://c.biancheng.net/stl/"} }; //调用 make_pair() 函数,生成键值对元素 //创建并初始化 multimap 容器 multimap<string, string>mymultimap{ make_pair("C语言教程", "http://c.biancheng.net/c/"), make_pair("Python教程", "http://c.biancheng.net/python/"), make_pair("STL教程", "http://c.biancheng.net/stl/") };
-
调用 multimap 类模板的拷贝(复制)构造函数,也可以初始化新的 multimap 容器:
multimap<string, string>newmultimap(mymultimap);
当有临时的 multimap 容器作为参数初始化新 multimap 容器时,其底层就会调用移动构造函数来实现初始化操作。
//创建一个会返回临时 multimap 对象的函数 multimap<string, string> dismultimap() { multimap<string, string>tempmultimap{ {"C语言教程", "http://c.biancheng.net/c/"},{"Python教程", "http://c.biancheng.net/python/"} }; return tempmultimap; } //调用 multimap 类模板的移动构造函数创建 newMultimap 容器 multimap<string, string>newmultimap(dismultimap());
-
从已有 multimap 容器中,选定某块区域内的所有键值对,用作初始化新 multimap 容器时使用。
//创建并初始化 multimap 容器 multimap<string, string>mymultimap{ {"C语言教程", "http://c.biancheng.net/c/"}, {"Python教程", "http://c.biancheng.net/python/"}, {"STL教程", "http://c.biancheng.net/stl/"} }; multimap<string, string>newmultimap(++mymultimap.begin(), mymultimap.end());
-
利用了 STL 模板库提供的
std::greater<T>
排序函数,实现令 multimap 容器对存储的键值对做降序排序:multimap<char, int, std::greater<char>>mymultimap{ {'a',1},{'b',2} };
multimap容器的成员方法
成员方法 | 功能 |
---|---|
begin() | 返回指向容器中第一个(注意,是已排好序的第一个)键值对的双向迭代器。如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
end() | 返回指向容器最后一个元素(注意,是已排好序的最后一个)所在位置后一个位置的双向迭代器,通常和 begin() 结合使用。如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
rbegin() | 返回指向最后一个(注意,是已排好序的最后一个)元素的反向双向迭代器。如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
rend() | 返回指向第一个(注意,是已排好序的第一个)元素所在位置前一个位置的反向双向迭代器。如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。 |
cbegin() | 和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
cend() | 和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
crbegin() | 和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
crend() | 和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的键值对。 |
find(key) | 在 multimap 容器中查找首个键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
lower_bound(key) | 返回一个指向当前 multimap 容器中第一个大于或等于 key 的键值对的双向迭代器。如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
upper_bound(key) | 返回一个指向当前 multimap 容器中第一个大于 key 的键值对的迭代器。如果 multimap 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
equal_range(key) | 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对。 |
empty() | 若容器为空,则返回 true;否则 false。 |
size() | 返回当前 multimap 容器中存有键值对的个数。 |
max_size() | 返回 multimap 容器所能容纳键值对的最大个数,不同的操作系统,其返回值亦不相同。 |
insert() | 向 multimap 容器中插入键值对。 |
erase() | 删除 multimap 容器指定位置、指定键(key)值或者指定区域内的键值对。 |
swap() | 交换 2 个 multimap 容器中存储的键值对,这意味着,操作的 2 个键值对的类型必须相同。 |
clear() | 清空 multimap 容器中所有的键值对,使 multimap 容器的 size() 为 0。 |
emplace() | 在当前 multimap 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。 |
emplace_hint() | 在本质上和 emplace() 在 multimap 容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数。 |
count(key) | 在当前 multimap 容器中,查找键为 key 的键值对的个数并返回。 |
和 map 容器相比,multimap 未提供 at() 成员方法,也没有重载 [] 运算符。这意味着,map 容器中通过指定键获取指定指定键值对的方式,将不再适用于 multimap 容器。其实这很好理解,因为 multimap 容器中指定的键可能对应多个键值对,而不再是 1 个。
#include <iostream>
#include <map> //map
using namespace std;
int main()
{
//创建并初始化 multimap 容器
multimap<char, int>mymultimap{ {'a',10},{'b',20},{'b',15}, {'c',30} };
//输出 mymultimap 容器存储键值对的数量
cout << mymultimap.size() << endl;
//输出 mymultimap 容器中存储键为 'b' 的键值对的数量
cout << mymultimap.count('b') << endl;
for (auto iter = mymultimap.begin(); iter != mymultimap.end(); ++iter) {
cout << iter->first << " " << iter->second << endl;
}
return 0;
}