<C++>map 容器快速上手|自定义数据类型排序的避坑理解(下)

简介: <C++>map 容器快速上手|自定义数据类型排序的避坑理解

1.4、map 插入和删除

功能:


map容器进行插入数据和删除数据

函数原型:


insert(elem); 在容器中插入元素。

clear(); 清除所有元素

erase(pos); 删除pos迭代器所指的元素,返回下一个元素的迭代器。

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

erase(key); 删除容器中值为key的元素。

代码示例:

// 插入和删除
void test03()
{
  //插入操作
  map<int, int> mp;
  //第一种插入方式
  mp.insert(pair<int, int>(1, 10));
  //第二种插入方式,推荐
  mp.insert(make_pair(2, 20));
  //第三种插入方式
  mp.insert(map<int, int>::value_type(3, 30));
  //第四种插入方式,不推荐:当不存在此值就会自动创建键,值为0
  mp[4] = 40;
  // 模拟误操作
  cout << "下标为6的值为:"<<mp[6] << endl;
  printInfo(mp);
  //删除,按迭代器
  mp.erase(mp.begin());
  printInfo(mp);
  // 删除,按下标
  mp.erase(3);
  mp.erase(6);
  printInfo(mp);
  //清空
  mp.erase(mp.begin(), mp.end());
  mp.clear();
  printInfo(mp);
}

1.5、map 查找和统计

功能:


对map容器进行查找数据以及统计数据

函数原型:


find(key); 查找key是否存在,若存在,返回该键对应的迭代器;若不存在,返回end();

count(key); 统计key的元素个数

代码示例:

// 查找和统计
void test04()
{
  map<int, int>mp;
  mp.insert(pair<int, int>(1, 10));
  mp.insert(pair<int, int>(2, 20));
  mp.insert(pair<int, int>(4, 40));
  mp.insert(pair<int, int>(3, 30));
  //查找
  map<int, int>::iterator pos = mp.find(3);
  if (pos != mp.end())
  {
    cout << "找到了元素 key = " << (*pos).first << " value = " << (*pos).second << endl;
  }
  else
  {
    cout << "未找到元素" << endl;
  }
  //统计
  int num = mp.count(2);
  cout << "num = " << num << endl;
}

2、自定义排序规则

与 set 容器一样,定义排序规则需要在创建容器的时候就指定,同样需要借助仿函数,也就是后面会提到的 谓词


2.1、内置数据类型的排序

// 内置数据类型排序
class descmp
{
public:
  bool operator()(int val1, int val2) const {
      // 指定为降序排列 
    return val1 > val2;
  }
};
void test05()
{
  cout << "降序排序插入:" << endl;
  map<int, int,descmp> mp;
  mp.insert(make_pair(3, 2));
  mp.insert(make_pair(7, 4));
  mp.insert(make_pair(6, 1));
  mp.insert(make_pair(8, 5));
  mp.insert(make_pair(1, 3));
  for (auto it = mp.begin(); it != mp.end(); it++) {
    cout << "key = " << it->first << " value = " << it->second << endl;
  }
}

f846da14167348fbb1bfb16a39637862.png


仿函数需要指定为 const 常函数类型,否则将会出现数据不完整错误


2.2、自定义数据类型的排序

进行自定义数据类型排序的时候要注意,使用仿函数定义排序规则是针对 键 的,因此要把定义的类、结构体放在泛型的第一个参数上(别问,问就是我看了半天源码才发现的…)


接下来看看我设计的小案例:

// 自定义数据类型排序
class Hero
{
public:
  // 构造方法
  Hero(string name, int age) :name(name), age(age) {}
  // 属性
  string name;
  int age;
};
class Cmp_hero
{
public:
  bool  operator()(const Hero& h1, const Hero& h2)const {
    return h1.age < h2.age;
  }
};
void test06()
{
  map<Hero, int, Cmp_hero> mh;
  Hero h1("赵云", 42);
  Hero h2("曹操", 43);
  Hero h3("孙策", 39);
  Hero h4("刘备", 40);
  Hero h5("关羽", 41);
  mh.insert(make_pair(h1, 12000));
  mh.insert(make_pair(h2, 14000));
  mh.insert(make_pair(h3, 10000));
  mh.insert(make_pair(h4, 18000));
  mh.insert(make_pair(h5, 16000));
  for (auto t = mh.begin(); t != mh.end(); t++) {
    cout << "姓名:" << t->first.name << " 年龄:" << t->first.age
      << " 赏金:" << t->second << endl;
  }
}

0224ba425fb84980a9f0f34aae282b2a.png


其实更合理的设计应该是按照赏金大小来排序,我之所以这样设计是想介绍一下当键是类的时候该怎么处理:仿函数参数列表中的变量若是 引用形式 必须用 const 修饰(若不是引用形式则不用加 const),而且函数也应该是常函数。


map 容器键值对存储的使用是非常广泛的,下篇博客来做一个员工分组的具体案例,巩固一些 STL常用容器的使用,大家可以订阅专栏,方便查阅和复习。


顾昀
+关注
目录
打赏
0
0
0
0
5
分享
相关文章
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
31 2
|
14天前
|
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
116 73
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
63 10
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
72 10
|
2月前
|
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
61 7
【C++面向对象——群体类和群体数据的组织】实现含排序功能的数组类(头歌实践教学平台习题)【合集】
1. **相关排序和查找算法的原理**:介绍直接插入排序、直接选择排序、冒泡排序和顺序查找的基本原理及其实现代码。 2. **C++ 类与成员函数的定义**:讲解如何定义`Array`类,包括类的声明和实现,以及成员函数的定义与调用。 3. **数组作为类的成员变量的处理**:探讨内存管理和正确访问数组元素的方法,确保在类中正确使用动态分配的数组。 4. **函数参数传递与返回值处理**:解释排序和查找函数的参数传递方式及返回值处理,确保函数功能正确实现。 通过掌握这些知识,可以顺利地将排序和查找算法封装到`Array`类中,并进行测试验证。编程要求是在右侧编辑器补充代码以实现三种排序算法
60 5
|
7月前
|
C++
C++ PCL 沿着自定义的平面做横截面(直通滤波)
C++ PCL 沿着自定义的平面做横截面(直通滤波)
75 0
【C++】map、set基本用法
本文介绍了C++ STL中的`map`和`set`两种关联容器。`map`用于存储键值对,每个键唯一;而`set`存储唯一元素,不包含值。两者均基于红黑树实现,支持高效的查找、插入和删除操作。文中详细列举了它们的构造方法、迭代器、容量检查、元素修改等常用接口,并简要对比了`map`与`set`的主要差异。此外,还介绍了允许重复元素的`multiset`和`multimap`。
89 3
【C++】map、set基本用法
【C++】unordered_map(set)
C++中的`unordered`容器(如`std::unordered_set`、`std::unordered_map`)基于哈希表实现,提供高效的查找、插入和删除操作。哈希表通过哈希函数将元素映射到特定的“桶”中,每个桶可存储一个或多个元素,以处理哈希冲突。主要组成部分包括哈希表、哈希函数、冲突处理机制、负载因子和再散列,以及迭代器。哈希函数用于计算元素的哈希值,冲突通过开链法解决,负载因子控制哈希表的扩展。迭代器支持遍历容器中的元素。`unordered_map`和`unordered_set`的插入、查找和删除操作在理想情况下时间复杂度为O(1),但在冲突较多时可能退化为O(n)。
50 5
【C++】map的模拟实现
C++中的`map`是STL中的一种关联容器,存储键值对且键唯一。`map`基于红黑树实现,自动按键排序,支持动态调整、复杂数据类型、丰富的成员函数及双向迭代器。插入、查找等操作保证了对数时间复杂度,适用于需要快速查找和有序存储的场景。
63 3

热门文章

最新文章