黑马c++ STL部分 笔记(9) map/multimap容器

简介: 黑马c++ STL部分 笔记(9) map/multimap容器

map中所有元素都是pair

pair中第一个元素为key(键值),起到索引作用,第二个元素为value(实值)

所有元素都会根据元素的键值自动排序

本质:

map/multimap属于关联式容器,底层结构是用二叉树实现。

优点

可以根据key值快速找到value值

map和multimap区别

map允许容器中有重复key值元素(value可以重复)

multimap允许容器中有重复key值元素(value可以重复)


1. map容器构造和赋值

// map容器构造和赋值
/*
构造:
map<T1, T2> mp; //map默认构造函数:
map(const map &mp); //拷贝构造函数
赋值:
map& operator=(const map &mp); //重载等号操作符
*/
#include <bits/stdc++.h>
using namespace std;
void printmap1(map<int, int> &m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << (*it).first << " " << (*it).second << endl;
  }
}
void test01()
{
  // 默认构造
  map<int, int> m;
  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(4, 40));
  m.insert(pair<int, int>(3, 30));
  printmap1(m); // 10 20 30 40 按key自动升序排序
  // 拷贝构造
  map<int, int> m2(m);
  printmap1(m2); // 10 20 30 40
  //=赋值
  map<int, int> m3;
  m3 = m2;
  printmap1(m3); // 10 20 30 40
}
int main()
{
  test01();
}
/*
总结:
map中所有元素都是成对出现,插入数据时候要使用对组
*/


2. map大小和交换

// map大小和交换
/*
size(); //返回容器中元素的数目
empty(); //判断容器是否为空
swap(st); //交换两个集合容器
*/
#include <bits/stdc++.h>
using namespace std;
void printmap1(map<int, int> &m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << (*it).first << " " << (*it).second << endl;
  }
}
void test01()
{
  // 默认构造
  map<int, int> m;
  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(4, 40));
  m.insert(pair<int, int>(3, 30));
  if (m.empty())
  {
    cout << "empty" << endl;
  }
  else
  {
    cout << "not empty" << endl;
    cout << m.size() << endl; // 4
  }
  map<int, int> m2;
  m2.insert(pair<int, int>(12, 10));
  m2.insert(pair<int, int>(24, 20));
  m2.insert(pair<int, int>(41, 40));
  m2.insert(pair<int, int>(35, 30));
  printmap1(m);
  /*1 10
  2 20
  3 30
  4 40*/
  printmap1(m2);
  /*12 10
  24 20
  35 30
  41 40*/
  m.swap(m2);
  printmap1(m);
  /*12 10
  24 20
  35 30
  41 40*/
  printmap1(m2);
  /*1 10
  2 20
  3 30
  4 40*/
}
int main()
{
  test01();
}
/*
总结:
统计大小 — size
判断是否为空 — empty
交换容器 — swap
*/


3. map插入和删除

// map插入和删除
/*
insert(elem); //在容器中插入'元素'。
clear(); //清除所有元素
erase(pos); //删除pos'迭代器'所指的元素,返回下一个元素的迭代器。
erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
erase(key); //删除容器中键值为key的元素。
*/
#include <bits/stdc++.h>
using namespace std;
void printmap1(map<int, int> &m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << (*it).first << " " << (*it).second << endl;
  }
}
void test01()
{
  map<int, int> m;
  // 插入
  m.insert(pair<int, int>(1, 10));
  m.insert(make_pair(2, 20));                 // 一般用这种
  m.insert(map<int, int>::value_type(3, 30)); // 不用记
  m[4] = 40;                                  // 不太建议用,因为m[5]若无值,则输出时输出key=5,value=0
  printmap1(m);                               // 1 10 2 20 3 30 4 40
  cout << endl;
  //[]不建议插数,但可以用[]来用key访问value
  cout << m[5] << endl; // 0
  cout << endl;
  // 删除
  m.erase(m.begin()); // 用pos删除
  printmap1(m);       // 2 20 3 30 4 40 5 0
  cout << endl;
  m.erase(3);   // 按key删除
  printmap1(m); // 2 20 4 40 5 0
  cout << endl;
  m.erase(3);   // 若无key=3,则不删
  printmap1(m); // 2 20 4 40 5 0
  cout << endl;
  m.erase(m.begin(), ++m.begin()); // 可以++,但不能+1/+3
  printmap1(m);                    // 4 40 5 0
  cout << endl;
  m.clear(); // 清空
  printmap1(m);
}
int main()
{
  test01();
}
/*
总结:
map插入方式很多,记住其一即可
插入 — insert
删除 — erase
清空 — clear
*/


4.  map查找和统计

// map查找和统计
/*
find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
count(key); //统计key的元素个数
*/
#include <bits/stdc++.h>
using namespace std;
void printmap1(map<int, int> &m)
{
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << (*it).first << " " << (*it).second << endl;
  }
}
void test01()
{
  // 查找
  map<int, int> m;
  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(3, 30));
  map<int, int>::iterator pos = m.find(3);
  if (pos != m.end())
  {
    cout << "find" << endl;                               // √
    cout << (*pos).first << " " << (*pos).second << endl; // 3 30
  }
  else
  {
    cout << " not find" << endl;
  }
  // 统计  map无重复key
  int num = m.count(3);
  cout << "num=" << num << endl; // 1
}
int main()
{
  test01();
}
/*
总结:
查找 — find (返回的是迭代器)
统计 — count (对于map,结果为0或者1;对于multimap,结果可以>0)
*/


5. map容器排序

5.1内置数据类型的排序

// map容器排序(默认升序)
/*
利用仿函数,可以改变排序规则(改为降序)
*/
#include <bits/stdc++.h>
using namespace std;
class cmp // 仿函数
{
public:
  bool operator()(int k1, int k2)
  {
    return k1 > k2;
  }
};
void test01()
{
  // 查找
  map<int, int> m;
  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(4, 40));
  m.insert(pair<int, int>(5, 50));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(3, 30));
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << (*it).first << " " << (*it).second << endl; // 1 10 2 20 3 30 4 40 5 50
  }
  cout << endl;
  map<int, int, cmp> m2;
  m2.insert(pair<int, int>(1, 10));
  m2.insert(pair<int, int>(4, 40));
  m2.insert(pair<int, int>(5, 50));
  m2.insert(pair<int, int>(2, 20));
  m2.insert(pair<int, int>(3, 30));
  for (map<int, int>::iterator it = m2.begin(); it != m2.end(); it++)
  {
    cout << (*it).first << " " << (*it).second << endl; // 5 50 4 40 3 30 2 20 1 10
  }
}
int main()
{
  test01();
}
/*
总结:
利用仿函数可以指定map容器的排序规则
对于自定义数据类型,map必须要指定排序规则,同set容器
*/


5.2自定义数据类型的排序

// map容器排序(默认升序)
/*
利用仿函数,可以改变排序规则(改为降序)
*/
#include <bits/stdc++.h>
using namespace std;
class person
{
public:
  person(string name, int age)
  {
    this->name = name;
    this->age = age;
  }
  string name;
  int age;
};
class cmp // 仿函数
{
public:
  bool operator()(person k1, person k2)
  {
    return k1.age > k2.age; // 按年龄排序
  }
};
void test01()
{
  // 查找
  map<person, int, cmp> m;
  person p1("A", 11);
  person p2("B", 22);
  person p3("C", 33);
  person p4("D", 44);
  person p5("E", 55);
  m.insert(pair<person, int>(p1, 10));
  m.insert(pair<person, int>(p3, 40));
  m.insert(pair<person, int>(p4, 50));
  m.insert(pair<person, int>(p2, 20));
  m.insert(pair<person, int>(p5, 30));
  for (map<person, int>::iterator it = m.begin(); it != m.end(); it++)
  {
    cout << (*it).first.name << " " << (*it).first.age << " " << (*it).second << endl;
  }
  /*
  E 55 30
  D 44 50
  C 33 40
  B 22 20
  A 11 10
  */
}
int main()
{
  test01();
}
/*
总结:
利用仿函数可以指定map容器的排序规则
对于自定义数据类型,map必须要指定排序规则,同set容器
*/


相关文章
|
6月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
169 2
|
6月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
321 73
|
7月前
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
6月前
|
存储 算法 C++
【c++丨STL】set/multiset的使用
本文深入解析了STL中的`set`和`multiset`容器,二者均为关联式容器,底层基于红黑树实现。`set`支持唯一性元素存储并自动排序,适用于高效查找场景;`multiset`允许重复元素。两者均具备O(logN)的插入、删除与查找复杂度。文章详细介绍了构造函数、迭代器、容量接口、增删操作(如`insert`、`erase`)、查找统计(如`find`、`count`)及`multiset`特有的区间操作(如`lower_bound`、`upper_bound`、`equal_range`)。最后预告了`map`容器的学习,其作为键值对存储的关联式容器,同样基于红黑树,具有高效操作特性。
259 3
|
7月前
|
存储 算法 C++
【c++丨STL】priority_queue(优先级队列)的使用与模拟实现
本文介绍了STL中的容器适配器`priority_queue`(优先级队列)。`priority_queue`根据严格的弱排序标准设计,确保其第一个元素始终是最大元素。它底层使用堆结构实现,支持大堆和小堆,默认为大堆。常用操作包括构造函数、`empty`、`size`、`top`、`push`、`pop`和`swap`等。我们还模拟实现了`priority_queue`,通过仿函数控制堆的类型,并调用封装容器的接口实现功能。最后,感谢大家的支持与关注。
326 1
|
8月前
|
C++ 容器
【c++丨STL】stack和queue的使用及模拟实现
本文介绍了STL中的两个重要容器适配器:栈(stack)和队列(queue)。容器适配器是在已有容器基础上添加新特性或功能的结构,如栈基于顺序表或链表限制操作实现。文章详细讲解了stack和queue的主要成员函数(empty、size、top/front/back、push/pop、swap),并提供了使用示例和模拟实现代码。通过这些内容,读者可以更好地理解这两种数据结构的工作原理及其实现方法。最后,作者鼓励读者点赞支持。 总结:本文深入浅出地讲解了STL中stack和queue的使用方法及其模拟实现,帮助读者掌握这两种容器适配器的特性和应用场景。
176 21
|
7月前
|
存储 算法 C++
深入浅出 C++ STL:解锁高效编程的秘密武器
C++ 标准模板库(STL)是现代 C++ 的核心部分之一,为开发者提供了丰富的预定义数据结构和算法,极大地提升了编程效率和代码的可读性。理解和掌握 STL 对于 C++ 开发者来说至关重要。以下是对 STL 的详细介绍,涵盖其基础知识、发展历史、核心组件、重要性和学习方法。
|
2月前
|
存储 监控 测试技术
如何将现有的应用程序迁移到Docker容器中?
如何将现有的应用程序迁移到Docker容器中?
246 57
|
2月前
|
存储 监控 Java
如何对迁移到Docker容器中的应用进行性能优化?
如何对迁移到Docker容器中的应用进行性能优化?
238 58
|
2月前
|
NoSQL Redis Docker
使用Docker Compose工具进行容器编排的教程
以上就是使用Docker Compose进行容器编排的基础操作。这能帮你更有效地在本地或者在服务器上部署和管理多容器应用。
301 11