<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常用容器的使用,大家可以订阅专栏,方便查阅和复习。


目录
相关文章
|
8月前
|
存储 C++
UE5 C++:自定义Http节点获取Header数据
综上,通过为UE5创建一个自定义HTTP请求类并覆盖GetResult方法,就能成功地从HTTP响应的Header数据中提取信息。在项目中使用自定义类,不仅可以方便地访问响应头数据,也可随时使用这些信息。希望这种方法可以为你的开发过程带来便利和效益。
305 35
|
10月前
|
存储 缓存 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 的奥秘,从入门到高效编程
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
242 9
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
240 2
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
185 0
|
10月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
6月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
185 0
|
6月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
279 0
|
8月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
319 12
|
9月前
|
设计模式 安全 C++
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
186 16

热门文章

最新文章