名字 | 描述 |
---|---|
begin | 返回指向容器中第一个(经过排序后)键值对的双向迭代器。 |
end | 返回指向容器最后一个元素(排序后)所在位置后一个位置的键值对的双向迭代器 |
rbegin | 返回容器逆序的第一个键值对的双向迭代器 |
rend | 返回容器逆序的最后一个元素的前一个位置的键值对双向迭代器 |
cbegin | 和begin()功能相同,在其基础上增加了 const 属性,不能用于修改元素。 |
cend | 和end()功能相同,在其基础上增加了 const 属性,不能用于修改元素。 |
crbegin | 和rbegin()功能相同,在其基础上增加了 const 属性,不能用于修改元素。 |
crend | 和rend()功能相同,在其基础上增加了 const 属性,不能用于修改元素。 |
名字 | 描述 |
---|---|
size | 返回存在键值对的个数 |
max_size | 返回元素个数的最大值。这个值非常大,一般是2^32-1 |
empty | 判断容器是否为空,为空返回true否则false |
名字 | 描述 |
---|---|
operator[] | map容器重载了 [] 运算符,只要知道 map 容器中某个键值对的键的值,就可以向获取数组中元素那样,通过键直接获取对应的值。 |
at | 找到 map 容器中 key 键对应的值,如果找不到,该函数会引发 out_of_range 异常。 |
名字 | 描述 |
---|---|
insert | 向map中插入键值对 |
erase | 删除map容器键值或者键值对 |
swap | 交换2个map容器中的所有键值对 |
clear | 清除map容器中的所有键值对 |
emplace | 在当前 map 容器中的指定位置处构造新键值对。其效果和插入键值对一样,但效率更高。 |
emplace_hint | 在本质上和 emplace() 在 map 容器中构造新键值对的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示键值对生成位置的迭代器,并作为该方法的第一个参数。 |
名字 | 描述 |
---|---|
find | 在 map 容器中查找键为 key 的键值对,如果成功找到,则返回指向该键值对的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
count | 在当前 map 容器中,查找键为 key 的键值对的个数并返回。注意,由于 map 容器中各键值对的键的值是唯一的,因此该函数的返回值最大为 1。 |
lower_bound | 返回一个指向当前 map 容器中第一个大于或等于 key 的键值对的双向迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
upper_bound | 返回一个指向当前 map 容器中第一个大于 key 的键值对的迭代器。如果 map 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。 |
equal_range | 该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的键为 key 的键值对(map 容器键值对唯一,因此该范围最多包含一个键值对)。 |
map<string, int> myMap; myMap["张三"] = 20; myMap["李四"] = 22; myMap["孙钱"] = 18; for (map<string, int>::iterator it = myMap.begin(); it != myMap.end(); it++) { cout << it->first << " :" << it->second << endl; } /* 输出 李四 :22 孙钱 :18 张三 :20 */
由以上代码可以看到,map会对元素进行排序,"李四"开头字母L
、"孙钱"开头字母S
、"张三"开头字母Z
,L < S < Z
,可见map默认以key值从小到大排序。
map<string, int> myMap; myMap["张三"] = 20; myMap["李四"] = 22; myMap["孙钱"] = 18; for (auto it = myMap.rbegin(); it != myMap.rend(); it++) { cout << it->first << " :" << it->second << endl; }
rbegin()和rend()则可从尾到头遍历。
size()
返回map中键值对的个数max_size()
map中能存储的最大值empty()
判断map是否为空:为空返回true,不为空返回falsemap<string, int> myMap; myMap["张三"] = 20; myMap["李四"] = 22; myMap["孙钱"] = 18; cout << myMap.size() << endl;//大小为3 cout << myMap.max_size() << endl;//最大容量:89478485 cout << myMap.empty() << endl;//非空即为0
[]
运算符,可以通过map[]通过key值访问其value。map<string, int> myMap; myMap["张三"] = 20; myMap["李四"] = 22; myMap["孙钱"] = 18; cout << myMap["张三"] << endl;//20 cout << myMap.at("张三") << endl;//20 cout << myMap["王五"] << endl;//0
这部分主要用于修改元素,如增删改查等操作。
因为map中存储的元素时键值对类型(pair),所以insert可以有两种插入方式:
(1)使用pair、value_type、make_pair()函数,插入一个键值对
map<string, int> myMap; myMap.insert(pair<string, int>("李四", 22)); myMap.insert(map<string, int>::value_type("张三", 20)); pair<map<string, int>::iterator, bool> ans;//定义返回值类型 ans = myMap.insert(make_pair("孙钱", 18)); cout << ans.first->first << ":" << ans.first->second << endl; myMap.insert(myMap.begin(), make_pair("赵六", 28));
注意,插入后的返回值是一个pair类型,pair.first是map的迭代器,pair.second为是否插入成功的返回值。
(2)在指定位置插入元素
map<string, int> myMap; myMap.insert(pair<string, int>("李四", 22)); myMap.insert(map<string, int>::value_type("张三", 20)); myMap.insert(make_pair("孙钱", 18)); myMap.insert(myMap.begin(), make_pair("赵六", 28));//在map头部后面插入 for (auto it = myMap.begin(); it != myMap.end(); it++) { cout << it->first << ":" << it->second << endl; }
但是通过显示的结果可知,即使指定在某个位置后插入,但是实际上map还是会根据key值将其排序。
注意,和前一种用法不一样的是,返回值是迭代器,而不是pair。
(3)在某个范围内插入元素,[first, last]
map<string, int> myMap; myMap.insert(pair<string, int>("李四", 22)); myMap.insert(map<string, int>::value_type("张三", 20)); myMap.insert(make_pair("孙钱", 18)); map<string, int> newMap; newMap.insert(myMap.begin(), myMap.end()); for (auto it : newMap) cout << it.first << ":" << it.second << endl;
(4)一次性插入多个键值对
map<string, int> myMap; myMap.insert({ {"李四", 22}, {"张三", 20} });//一次性插入两个键值对 myMap.insert(make_pair("孙钱", 18));
删除元素,输入参数为迭代器,有以下两种遍历删除元素的方法:
(1)通过迭代器删除元素
因为erase的返回值是下一个迭代器的指针,所以可以用返回值做下一次删除的元素
map<string, int> myMap; myMap.insert(map<string, int>::value_type("张三", 20)); myMap.insert(map<string, int>::value_type("李四", 22)); myMap.insert(map<string, int>::value_type("孙钱", 18)); for (auto it = myMap.begin(); it != myMap.end(); ) { it = myMap.erase(it); } cout << myMap.empty() << endl;
根据后++
的特点,先删除后it偏移。
map<string, int> myMap; myMap.insert(map<string, int>::value_type("张三", 20)); myMap.insert(map<string, int>::value_type("李四", 22)); myMap.insert(map<string, int>::value_type("孙钱", 18)); for (auto it = myMap.begin(); it != myMap.end(); ) { myMap.erase(it++); } cout << myMap.empty() << endl;
(2)通过key值删除元素
map<string, int> myMap; myMap.insert({ {"李四", 22}, {"张三", 20} }); myMap.emplace_hint(myMap.begin(), make_pair("孙钱", 18)); myMap.erase("李四");//删除key值为李四的元素
swap交换两个map的内容,两个map的所有内容均交换。
map<string, int> myMap; myMap.insert(map<string, int>::value_type("张三", 20)); myMap.insert(map<string, int>::value_type("李四", 22)); myMap.insert(map<string, int>::value_type("孙钱", 18)); map<string, int> myMap2; myMap2["王五"] = 30; myMap2["赵六"] = 50; myMap.swap(myMap2); for (auto it = myMap.begin(); it != myMap.end(); it++) { cout << it->first << ":" << it->second << endl; }
clear清空map的键值对,size = 0。
map<string, int> myMap; myMap.insert(map<string, int>::value_type("张三", 20)); myMap.insert(map<string, int>::value_type("李四", 22)); myMap.insert(map<string, int>::value_type("孙钱", 18)); myMap.clear(); cout << myMap.empty() << endl;
用法和insert一样,只是内部实现机制不同,emplace更快,但是只能插入一个键值对。
emplace的插入可以,将创建新键值对所需的数据作为参数直接传入即可,此方法可以自行利用这些数据构建出指定的键值对。
map<string, int> myMap; myMap.emplace(map<string, int>::value_type("张三", 20));//法1 myMap.emplace(pair<string, int>("李四", 22));//法2 myMap.emplace("赵六", 30);
emplace_hint有点类似于insert的第二种用法,在指定位置插入。
但是,emplace_hint和emplace一样,可以将数据参数直接输入。
第一个参数是要插入的位置,接下来第二、三个参数分别是key 和 value。
map<string, int> myMap; myMap.insert({ {"李四", 22}, {"张三", 20} }); myMap.emplace_hint(myMap.begin(), "孙钱", 18);
当然,和insert一样,指定位置插入,但是map仍然会根据key值大小进行排序。
这部分操作用于查找元素,计算元素大小。
map有find方法,需和algorithm库的find区别。map的find方法寻找键值对中的键值,返回一个迭代器。如果迭代器不是map.end()
,那么说明找到元素,返回该元素的迭代器。
map<string, int> myMap; myMap.insert({ {"李四", 22}, {"张三", 20} }); myMap.emplace_hint(myMap.begin(), make_pair("孙钱", 18)); auto it = myMap.find("李四");//寻找是否有名为"赵四"的人 if (it != myMap.end()) { cout << it->first << ":" << it->second << endl; }
map和set两种容器的底层结构都是红黑树,所以容器中不会出现相同的元素,因此count()的结果只能为0和1。
所以可以用count
判断map是否有某键值对。
map<string, int> myMap; myMap.insert({ {"李四", 22}, {"张三", 20} }); myMap.emplace_hint(myMap.begin(), make_pair("孙钱", 18)); cout << myMap.count("张三") << endl;//输出1
在STL里有lower_bound函数,用于在有序容器中找到第一个大于val值的迭代器。
同样的,在map中有该方法,返回大于或等于某个键值key
的迭代器。
map<int, int> myMap; myMap[1] = 2; myMap[2] = 4; myMap[3] = 7; myMap[5] = 8; myMap[6] = 9; auto it = myMap.lower_bound(3); if (it != myMap.end()) { cout << it->first << ":" << it->second << endl;//3:7 }
和lower_bound类似,不过upper_bound返回的是大于某个键值key
的迭代器。
map<int, int> myMap; myMap[1] = 2; myMap[2] = 4; myMap[3] = 7; myMap[5] = 8; myMap[6] = 9; auto it = myMap.upper_bound(3); if (it != myMap.end()) { cout << it->first << ":" << it->second << endl;//5:8 }
pair<const_iterator,const_iterator> equal_range (const key_type& k) const; pair<iterator,iterator> equal_range (const key_type& k);
如上是map中equal_range的原形,返回值是一个pair类型,pair类型里是两个迭代器,pair::first返回的值等于lower_bound的返回值,即大于等于某个值的第一个值的迭代器;pair::second返回的值等于upper_bound返回的值,即大于某个值的第一个值的迭代器。
所以,equal_range用于计算某个值的所有插入的元素。因为我们可能插入(insert)了很多元素,但是实际上只有一个值有效,也就是第一个插入的值。equal_range就可以为multimap
计算所有插入的元素。
而map
不论传入多少个都只有一个值,equal_range得到也只有一个值。
以下是multimap的equal_range
:
multimap<int, int> myMap; myMap.insert(make_pair(1, 5)); myMap.insert(make_pair(2, 4)); myMap.insert(make_pair(3, 6)); myMap.insert(make_pair(3, 5)); myMap.insert(make_pair(3, 4)); auto ret = myMap.equal_range(3); for (auto it = ret.first; it != ret.second; it++) { cout << it->first << ":" << it->second << endl; } //输出: /* 3:6 3:5 3:4 */