博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++ map 和 multimap 容器
阅读量:509 次
发布时间:2019-03-07

本文共 7906 字,大约阅读时间需要 26 分钟。

map/multimap的简介

map是标准的关联式容器,一个map里存储的元素是一个键值对序列,叫做(key,value)键值对。它提供基于key快速检索数据的能力。

  1. map中key值是唯一的。集合中的元素按一定的顺序排列。元素插入过程是按排序规则插入,所以不能指定插入位置。
  2. map底层的具体实现是采用红黑树变体的平衡二叉树的数据结构。在插入操作、删除和检索操作上比vector快很多。
  3. map可以直接存取key所对应的value,支持[]操作符,如map[key]=value。
  4. 使用时必须包含头文件#include <map>

multimap与map的区别:

map支持唯一键值,每个键只能出现一次;而multimap中相同键可以出现多次。multimap不支持[]操作符。

map/multimap容器 和 set/multiset容器都是差不多的,只是map/mulitmap比他们多了一个键值!

如果不懂set/multiset容器的可以点下面链接:

当然,map/multimap容器也有仿函数,因为在之前的文章中,已经详细讲过了,所以这里就不在讲了,如果不懂的可以点下面链接去学习:


定义
// 无参	map
m1; map
m2; map
m3; map
m4; // 带参 map
m5(m1.begin(), m1.end()); // 迭代器 map
m6(m3); // 调用拷贝构造函数 map
m7 = m4; // 调用了赋值构造函数

还可以用各种指针类型或自定义类型


插入

// 方式一 构造一个pair,然后插入,如果键存在,则插入失败

m1.insert(pair<int, string>(1, “张三”));

// 方式二 使用make_pair

m1.insert(make_pair(2, “李四”));

// 方式三 使用value_type,相当于pair<int, string>

m1.insert(map<int, string>::value_type(3, “王五”));

// 方式四 使用 [] 重载,如果键值对已经存在,则覆盖原值

m1[4] = “赵六”;
m1[4] = “韩七”;

注意:

  1. 方式一 至 方式三的返回值类型都是一样的,都是

    pair<iterator,bool> 类型

  2. 第四种方法非常直观,但碰到相同的键时会进行覆盖操作。比如插入key 为4的键值时,先在mapStu中查找主键为4的项,若不存在,则将一个键为4,值为默认初始化值的对组插入到mapStu中,然后再将值修改成“赵六”。若发现已存在4这个键,则修改这个键对应的value。

  3. string strName = mapStu[8]; //取值操作或插入操作

  4. 只有当mapStu存在8这个键时才是正确的取操作,否则会自动插入一个实例,键为8,值为默认构造时的初始化值。

下面测试代码 函数 test1 中会有详细案例


迭代器

// 返回容器中第一个数据的迭代器

m1.begin();

// 返回容器中最后一个数据之后的迭代器

m1.end();

// 返回容器中倒数第一个元素的迭代器

m1.rbegin();

// 返回容器中倒数最后一个元素的后面的迭代器

m1.rend();

// 使用迭代器方式输出容器里的值

for (map
::iterator it = m1.begin(); it != m1.end(); it++) {
cout << "key:" << (*it).first << " value:" << (*it).second << endl;}

排序

map 和 multimap 容器默认存储时是顺序存储的,即

map<int, string> m1; 相等于: map<int, string, less<int>> m1;

也可以使用greater定义一个容器,使其默认逆序存储,即

map<int, string, greater<int>> m2;

在此条链接中会有详细解析:

// 交换容器中的元素

m3.swap(m2);


// 返回容器中元素的个数

m1.size();

// 判断容器是否为空

m1.empty(); // 为空返回真,不为空返回假

//删除迭代器所指的元素,返回下一个元素的迭代器

m1.erase(m1.begin());

//删除区间[beg,end)的所有元素,返回下一个元素的迭代器

m1.erase(beg, end);

//删除容器中key为key的对组,返回删除的对组个数

m1.erase(8);

// 删除容器中所有的元素

m1.clear();


查找

map方式

// 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();

/*---map---*/// 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();map
::iterator it = m1.find(5);if (it != m1.end()) {
cout << "m1.find(5) = " << (*it).second << endl;} else {
cout << "没找到!!!" << endl;}

multimap方式

// 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();

/*---multimap---*/// 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end();multimap
::iterator mit = m2.find(111);if (mit != m2.end()) {
for (; mit != m2.end(); mit++) {
if ((*mit).first == 111) {
cout << "m2.find(111) = " << (*mit).second << endl; } else {
break; } }}

// 返回容器中键值为key的对组个数。对map来说,要么是0,要么是1;对multimap来说,值>=0

m1.count(222);

// 返回第一个 >= key 元素的迭代器

m1.lower_bound(2);

// 返回第一个 > key 元素的迭代器

m1.upper_bound(2);

//返回容器中key与keyElem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end)

//m1.equal_range(keyElem);
m1.equal_range(7);

返回值是: pair<iterator, iterator> 类型

在下面测试代码函数 test7 中会有详细案例。


测试代码:

#include #include 
#include
#include
using namespace std;// 定义void test1(void) {
// 无参 map
m1; map
m2; map
m3; map
m4; m1.insert(pair
(1, "张三")); m1.insert(pair
(2, "李四")); // 带参 map
m5(m1.begin(), m1.end()); // 迭代器 map
m6(m3); // 调用拷贝构造函数 map
m7 = m4; // 调用了赋值构造函数 for (map
::iterator it = m1.begin(); it != m1.end(); it++) { cout << "key:" << (*it).first << " value:" << (*it).second << endl; }}// insert插入void test2(void) { map
m1; // 方式一 构造一个pair,然后插入,如果键存在,则插入失败 m1.insert(pair
(1, "张三")); // 方式二 使用make_pair m1.insert(make_pair(2, "李四")); // 方式三 使用value_type,相当于pair
m1.insert(map
::value_type(3, "王五")); // 方式四 使用 [] 重载,如果键值对已经存在,则覆盖原值 m1[4] = "赵六"; m1[4] = "韩七"; m1[5] = m1[6]; // 应为两个都是新值,所以他们创建键后,值默认为空 m1[7] = m1[4]; // 将键值为4里的值赋值给键值为7的值 m1[0] = m1[8]; // 新键赋值给旧键,它两的值都为空 // 方式一 至 方式三的返回值类型都是一样的 pair
::iterator, bool> ret1 = m1.insert(pair
(9, "刘八")); pair
::iterator, bool> ret2 = m1.insert(make_pair(10, "杨九")); pair
::iterator, bool> ret3 = m1.insert(map
::value_type(11, "吴十")); if (ret1.second == true) { cout << "插入成功!value:" << (*(ret1.first)).second << endl; } else { cout << "插入失败!" << endl; } for (map
::iterator it = m1.begin(); it != m1.end(); it++) { cout << "key:" << (*it).first << " value:" << (*it).second << endl; }}// 迭代器void test3(void) { map
m1; m1.begin(); // 返回容器中第一个数据的迭代器。 m1.end(); // 返回容器中最后一个数据之后的迭代器。 m1.rbegin(); // 返回容器中倒数第一个元素的迭代器。 m1.rend(); // 返回容器中倒数最后一个元素的后面的迭代器。}// 排序void test4(void) { map
m1; // 默认是less顺序排序 //map
> m1; m1.insert(pair
(1, "张三")); m1.insert(pair
(2, "李四")); m1.insert(pair
(3, "王五")); m1.insert(pair
(4, "赵六")); // 可以使用greater逆序排序 map
> m2; m2.insert(pair
(1, "韩七")); m2.insert(pair
(2, "刘八")); m2.insert(pair
(3, "杨九")); map
> m3; // 交换容器中的元素 m3.swap(m2); cout << "m1 ==> less
:" << endl; for (map
::iterator it = m1.begin(); it != m1.end(); it++) { cout << "key:" << (*it).first << " value:" << (*it).second << endl; } cout << "m3 ==> greater
:" << endl; for (map
::iterator it = m3.begin(); it != m3.end(); it++) { cout << "key:" << (*it).first << " value:" << (*it).second << endl; }}// 大小void test5(void) { map
m1; m1.insert(pair
(1, "张三")); m1.insert(pair
(2, "李四")); m1.insert(pair
(3, "王五")); m1.insert(pair
(4, "赵六")); // 返回容器中元素的个数 m1.size(); // 判断容器是否为空 m1.empty(); // 为空返回真,不为空返回假 if (!m1.empty()) { cout << "容器元素个数为:" << m1.size() << endl; } else { cout << "容器为空!" << endl; }}// 删除void test6(void) { map
m1; m1.insert(pair
(1, "张三")); m1.insert(pair
(2, "李四")); m1.insert(pair
(3, "王五")); m1.insert(pair
(4, "赵六")); m1.insert(pair
(5, "韩七")); m1.insert(pair
(6, "刘八")); m1.insert(pair
(7, "杨九")); m1.insert(pair
(8, "吴十")); //删除迭代器所指的元素,返回下一个元素的迭代器 m1.erase(m1.begin()); // 李四,王五,赵六,韩七,刘八,杨九,吴十 map
::iterator beg = m1.begin(); beg++; map
::iterator end = m1.begin(); end++; end++; end++; //删除区间[beg,end)的所有元素,返回下一个元素的迭代器 m1.erase(beg, end); // 李四,韩七,刘八,杨九,吴十 //删除容器中key为key的对组,返回删除的对组个数 m1.erase(8); // 李四,韩七,刘八,杨九 for (map
::iterator it = m1.begin(); it != m1.end(); it++) { cout << "key:" << (*it).first << " value:" << (*it).second << endl; } // 删除容器中所有的元素 m1.clear();}// 查找void test7(void) { map
m1; multimap
m2; m1.insert(pair
(1, "张三")); m1.insert(pair
(2, "李四")); m1.insert(pair
(3, "王五")); m1.insert(pair
(4, "赵六")); m1.insert(pair
(5, "韩七")); m1.insert(pair
(6, "刘八")); m1.insert(pair
(7, "杨九")); m1.insert(pair
(8, "吴十")); m2.insert(pair
(111, "张三")); m2.insert(pair
(111, "李四")); m2.insert(pair
(222, "王五")); m2.insert(pair
(222, "赵六")); /*---map---*/ // 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end(); map
::iterator it = m1.find(5); if (it != m1.end()) { cout << "m1.find(5) = " << (*it).second << endl; } else { cout << "没找到!!!" << endl; } /*---multimap---*/ // 查找键key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回map.end(); multimap
::iterator mit = m2.find(111); if (mit != m2.end()) { for (; mit != m2.end(); mit++) { if ((*mit).first == 111) { cout << "m2.find(111) = " << (*mit).second << endl; } else { break; } } } //返回容器中键值为key的对组个数。对map来说,要么是0,要么是1;对multimap来说,值>=0 m1.count(222); //返回第一个 >= key 元素的迭代器 it = m1.lower_bound(2); if (it != m1.end()) { cout << "找到啦!==> " << (*it).second << endl; } else { cout << "没找到!" << endl; } // 返回第一个 > key 元素的迭代器 it = m1.upper_bound(2); if (it != m1.end()) { cout << "找到啦!==> " << (*it).second << endl; } else { cout << "没找到!" << endl; } //返回容器中key与keyElem相等的上下限的两个迭代器。上限是闭区间,下限是开区间,如[beg,end) //m1.equal_range(keyElem); pair
::iterator, map
::iterator> iit = m1.equal_range(7); // 第一个迭代器 if (iit.first != m1.end()) { cout << "begin ==> " << (*iit.first).second << endl; } else { cout << "没找到!" << endl; } // 第二个迭代器 if (iit.second != m1.end()) { cout << "end ==> " << (*iit.second).second << endl; } else { cout << "没找到!" << endl; }}int main(void) { //test1(); //test2(); //test3(); //test4(); //test5(); //test6(); //test7(); system("pause"); return 0;}

总结:

STL容器中,所有容器的接口用法都是差不多的,所以说其实并不难,只要理解了一种,其他的容器用法都全会了。

转载地址:http://hrpjz.baihongyu.com/

你可能感兴趣的文章