<C++>快速掌握set 容器|去重的底层原因|使用仿函数定义排序规则(下)

简介: <C++>快速掌握set 容器|去重的底层原因|使用仿函数定义排序规则

2、set 和 multiset 插入数据特点不同的原因

上面提到二者的不同点在于是否可以插入不同的数据,那么就来看看二者insert插入方法的源码


2.1、set 中的insert 源码分析

查看set 中的insert 源码:

0e2285f0026e4213a2ce2f0fdf191539.png



可以看到这里的insert返回值类型是一个pair二元组,包含迭代器类型和布尔类型

那么再进行插入操作的时候,如果检查到容器中已经有相同元素,就会返回false,不进行插入

有关二元组的创建将在下面解释

2.2、pair 对组的创建及使用

功能描述:


成对出现的数据,利用对组可以返回两个数据

两种创建方式:


pair<type, type> p ( value1, value2 );

pair<type, type> p = make_pair( value1, value2 );

代码示例:

// pair 对组的使用 make_pair()
void testPair() {
  // 默认构造
  pair<string, int> pre("微凉", 10);
  pair<string, int> ptr = make_pair("秋意", 24);
  // 获取值
  cout << pre.first << ptr.first << "\n" << pre.second << ptr.second << endl;
}

6231509ef11f4c6a9220da9e4a5d9054.png


推荐使用make_pair的方式创建二元组,这样看起来比较清晰

二元组通过调用first和second来访问对应的属性值

2.3、multiset 中的insert 源码分析

查看multiset 中的insert 源码:


6af71603ce3140d18969f0eb2547be08.png


multiset 中的insert 返回值类型是一个迭代器,并没有布尔类型

所以可以插入重复数据

3、内置与自定义数据类型的排序规则

set 容器插入时默认自动升序排序,那么怎么修改排序规则呢:

使用仿函数来指定排序规则

3.1、内置数据类型的排序

写一个类,重载类内的函数运算符() :

// 修改 set 容器的排序规则
class Cmp {
public:
  bool operator()(int v1,int v2) const
  {
    return v1 > v2;
  }
};
void test7() {
  // 默认是升序
  set<int> s1;
  s1.insert(1);
  s1.insert(0);
  s1.insert(2);
  s1.insert(4);
  printSet(s1);
  // 修改为降序,借助仿函数
  set<int, Cmp> s2;
  s2.insert(1);
  s2.insert(0);
  s2.insert(2);
  s2.insert(4);
  for (auto it = s2.begin(); it != s2.end(); it++) {
    cout << *it << " ";
  }
}

要注意的是重载的函数需要是常函数,要加上const关键字

重载的细节可以参考我这篇博客:详解重载函数调用运算符

创建set 容器的时候就要指定排序规则,在尖括号中这样表示:set<int, Cmp>

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

set 容器插入自定义数据的时候如果不指定排序规则,默认的升序排序也无法进行,因此需要事先指定排序规则:

// 定义Person 类
class Person {
  int age;
  string name;
public:
  Person(string name, int age) {
    this->name = name;
    this->age = age;
  }
  int getAge() const {
    return this->age;
  }
  string getName() const {
    return this->name;
  }
};
// 自定义排序规则
class Compare {
public:
  bool operator()(const Person &p1, const Person &p2)const {
    return p1.getAge() > p2.getAge();
  }
};
void test8() {
  set<Person, Compare> s;
  Person p1("叶落", 20);
  Person p2("微凉", 24);
  Person p3("秋意", 22);
  Person p4("秋白", 18);
  s.insert(p1);
  s.insert(p2);
  s.insert(p3);
  s.insert(p4);
  for (auto it = s.begin(); it != s.end(); it++) {
    cout << "姓名:" << it->getName() << "\t年龄:" << it->getAge()<<endl;
  }
}

运行效果:


a2fbeffc564a42ccaa2d37c9946df330.png


自定义数据类型重载时的要求比较严格:

不仅函数需要加const限制,参数列表中也都要加const

由于Person类中的属性采用了封装,那么在对应的get 方法中也要是常函数

希望以此文章帮助大家快速学会、复习set容器的使用,创作不易,希望大家能够点赞支持!


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

热门文章

最新文章