【C++ STL有序关联容器】set 集合

文章目录

  • 【 1. 基本原理 】
  • 【 2. set 的定义 】
    • 2.1 调用默认构造函数,创建空的 set 容器
    • 2.2 在创建 set 容器的同时,对其进行初始化
    • 2.3 拷贝构造的方式创建
    • 2.4 取已有 set 容器中的部分元素,来初始化新 set 容器
    • 2.5 修改排序规则的方式创建
  • 【 3. set 包含的成员方法 】
    • 实例 - 正向迭代器的定义方式 遍历 set

【 1. 基本原理 】

  • 和 map、multimap 容器不同, 使用 set 容器存储的各个键值对,要求 键 key 和值 value 必须相等
    如下所示有 2 组键值对数据:
    {<‘a’, 1>, <‘b’, 2>, <‘c’, 3>}
    {<‘a’, ‘a’>, <‘b’, ‘b’>, <‘c’, ‘c’>}
    显然,第一组数据中各键值对的键和值不相等,而第二组中各键值对的键和值对应相等。对于 set 容器来说,只能存储第 2 组键值对,而无法存储第一组键值对。
  • 基于 set 容器的这种特性,当使用 set 容器存储键值对时,只需要为其提供各键值对中的 value 值(也就是 key 的值) 即可。
    仍以存储上面第 2 组键值对为例,只需要为 set 容器提供 {‘a’,‘b’,‘c’} ,该容器即可成功将它们存储起来。
  • map、multimap 容器都会自行根据键的大小对存储的键值对进行排序,set 容器也会如此,只不过 set 容器中各键值对的键 key 和值 value 是相等的,根据 key 排序,也就等价为根据 value 排序
  • 使用 set 容器存储的各个元素的值必须各不相同。更重要的是,从语法上讲 set 容器并没有强制对存储元素的类型做 const 修饰,即 set 容器中存储的元素的值是可以修改的。但是,C++ 标准为了防止用户修改容器中元素的值,对所有可能会实现此操作的行为做了限制,使得在正常情况下, 用户是无法做到修改 set 容器中元素的值的

对于初学者来说,切勿尝试直接修改 set 容器中已存储元素的值,这很有可能破坏 set 容器中元素的有序性,最正确的修改 set 容器中元素值的做法是:先删除该元素,然后再添加一个修改后的元素。

  • set 容器定义于 <set>头文件,并位于 std 命名空间中。因此如果想在程序中使用 set 容器,该程序代码应先包含如下语句:
#include <set>
using namespace std;
  • set 容器的类模板定义如下:
    • 由于 set 容器存储的各个键值对,其键和值完全相同,也就意味着它们的类型相同,因此 set 容器类模板的定义中,仅有第 1 个参数用于设定存储数据的类型
    • 对于 set 类模板中的 3 个参数,后 2 个参数自带默认值,且几乎所有场景中只需使用前 2 个参数,第 3 个参数不会用到。
template < class T,                        // 键 key 和值 value 的类型class Compare = less<T>,        // 指定 set 容器内部的排序规则class Alloc = allocator<T>      // 指定分配器对象的类型> class set;
  • set 支持 双向迭代器

【 2. set 的定义 】

2.1 调用默认构造函数,创建空的 set 容器

  • 基本语法
    • 该容器采用默认的std::less规则,会对存储的 DataType 类型元素做升序排序。注意,由于 set 容器支持随时向内部添加新的元素,因此创建空 set 容器的方法是经常使用的。
set <DataType> myset;

2.2 在创建 set 容器的同时,对其进行初始化

  • 基本语法
set<string> myset{"http://c.biancheng.net/java/","http://c.biancheng.net/stl/","http://c.biancheng.net/python/"};
  • 由此即创建好了包含 3 个 string 元素的 myset 容器。由于其采用默认的 std::less 规则,因此其内部存储 string 元素的顺序如下所示:
"http://c.biancheng.net/java/"
"http://c.biancheng.net/python/"
"http://c.biancheng.net/stl/"

2.3 拷贝构造的方式创建

  • set 类模板中还提供了拷贝构造函数,可以实现在创建新 set 容器的同时,将已有 set 容器中存储的所有元素全部复制到新 set 容器中。
  • 基本语法:
    在创建 myset1 容器的基础上,还会将 myset1 容器中存储的所有元素,全部复制给 myset2 容器一份。
set<DataType> myset2(myset1);
//等同于
set<DataType> myset2= myset1
  • 移动构造函数的方式创建 set
    C++ 11 标准还为 set 类模板新增了 移动构造函数,其功能是实现创建新 set 容器的同时,利用临时的 set 容器为其初始化。比如:
    • 由于 retSet() 函数的返回值是一个临时 set 容器,因此在初始化 copyset 容器时,其内部调用的是 set 类模板中的移动构造函数,而非拷贝构造函数。
    • 无论是调用复制构造函数还是调用拷贝构造函数,都必须保证这 2 个容器的类型完全一致。
set<string> retSet() {set<string> myset{ "http://c.biancheng.net/java/","http://c.biancheng.net/stl/","http://c.biancheng.net/python/" };return myset;
}
set<string> copyset(retSet());//或者set<string> copyset = retSet();

2.4 取已有 set 容器中的部分元素,来初始化新 set 容器

  • 在第 3 种方式的基础上,set 类模板还支持取已有 set 容器中的部分元素,来初始化新 set 容器。
  • 基本语法
set<string> myset{ "http://c.biancheng.net/java/","http://c.biancheng.net/stl/","http://c.biancheng.net/python/" };
set<string> copyset(++myset.begin(), myset.end());
  • 由此初始化的 copyset 容器,其内部仅存有如下 2 个 string 字符串:
"http://c.biancheng.net/python/"
"http://c.biancheng.net/stl/"

2.5 修改排序规则的方式创建

  • 以上几种方式创建的 set 容器,都采用了默认的std::less规则。其实,可以 借助 set 类模板定义中第 2 个参数,手动修改 set 容器中的排序规则
  • 基本语法
set<string,greater<string> > myset{"http://c.biancheng.net/java/","http://c.biancheng.net/stl/","http://c.biancheng.net/python/"};
  • 通过选用 std::greater 降序规则,myset 容器中元素的存储顺序为:
"http://c.biancheng.net/stl/"
"http://c.biancheng.net/python/"
"http://c.biancheng.net/java/"

【 3. set 包含的成员方法 】

成员方法功能
begin()返回指向容器中第一个(注意,是已排好序的第一个)元素的双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
end()返回指向容器最后一个元素(注意,是已排好序的最后一个)所在位置后一个位置的双向迭代器,通常和
rbegin()返回指向最后一个(注意,是已排好序的最后一个)元素的反向双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。
rend()返回指向第一个(注意,是已排好序的第一个)元素所在位置前一个位置的反向双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的反向双向迭代器。
cbegin()和 begin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
cend()和 end() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
crbegin()和 rbegin() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
crend()和 rend() 功能相同,只不过在其基础上,增加了 const 属性,不能用于修改容器内存储的元素值。
find(val)在 set 容器中查找值为 val 的元素,如果成功找到,则返回指向该元素的双向迭代器;反之,则 返回 .endl() 迭代器。另外,如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
lower_bound(val)返回一个指向当前 set 容器中第一个大于或等于 val 的元素的双向迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
upper_bound(val)返回一个指向当前 set 容器中 第一个大于 val 的元素 的迭代器。如果 set 容器用 const 限定,则该方法返回的是 const 类型的双向迭代器。
equal_range(val)该方法返回一个 pair 对象(包含 2 个双向迭代器),其中 pair.first 和 lower_bound() 方法的返回值等价,pair.second 和 upper_bound() 方法的返回值等价。也就是说,该方法将返回一个范围,该范围中包含的值为 val 的元素(set 容器中各个元素是唯一的,因此该范围最多包含一个元素)。
empty()若容器为空,则返回 true;否则 false。
size()返回当前 set 容器中存有元素的个数。
max_size()返回 set 容器所能容纳元素的最大个数,不同的操作系统,其返回值亦不相同。
insert()向 set 容器中插入元素。
erase()删除 set 容器中存储的元素。
swap()交换 2 个 set 容器中存储的所有元素。这意味着,操作的 2 个 set 容器的类型必须相同。
clear()清空 set 容器中所有的元素,即令 set 容器的 size() 为 0。
emplace()在当前 set 容器中的指定位置直接构造新元素。其效果和 insert() 一样,但效率更高。
emplace_hint()在本质上和 emplace() 在 set 容器中构造新元素的方式是一样的,不同之处在于,使用者必须为该方法提供一个指示新元素生成位置的迭代器,并作为该方法的第一个参数。
count(val)在当前 set 容器中,查找值为 val 的元素的个数,并返回。注意,由于 set 容器中各元素的值是唯一的,因此该函数的返回值最大为 1。

实例 - 正向迭代器的定义方式 遍历 set

  • 键盘输入 5 个整数,将这些数据保存到set中,采用迭代器正向遍历set中的元素并输出。
#include <set>
#include <iostream>
using namespace std;
int main() {set<int>s;int x;for (int j = 0; j < 5; ++j) {cin >> x;s.insert(x);}set<int>::iterator t;for (t = s.begin(); t != s.end(); ++t) {cout << *t << " ";}return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/601946.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙Native输出so动态库,并提供给第三方导入使用

前言&#xff1a; DevEco Studio版本&#xff1a;4.0.0.600 API:9 最近在学习鸿蒙的Native输出so动态库&#xff0c;下面就给大家分享下我的学习心得及在实现过程中遇到的问题。 实现需求&#xff1a;通过so库输出文本内容 “你好&#xff0c;鸿蒙&#xff01;” 参考资料…

计算机网络基础(一)

目录 一.互联网和因特网 二.因特网的发展历程 三.因特网的功能 3.1边缘部分 3.1.1&#xff1a;客户服务器方式&#xff08;C/S方式&#xff09; 3.1.2&#xff1a;对等方式 3.2.核心部分 3.2.1&#xff1a;电路交换 3.2.2.报文交换 3.2.3&#xff1a;分组交换 四.计…

matlab学习001-简单的矩阵输入及绘制信号曲线

目录 1&#xff0c;熟悉简单的矩阵输入 1.1&#xff0c;创建矩阵 1.2&#xff0c;在命令行调用文件中的变量 1.3&#xff0c;ones函数 1.4&#xff0c;who和whos的使用 2&#xff0c;绘制信号曲线 2.1&#xff0c;实指数信号 2.2&#xff0c;频率为50Hz的周期方波信号…

红米K60更换后摄镜片

红米K60更换后摄镜片 拆后盖&#xff1a; 热风枪80加热后盖四周边缘&#xff0c;摸起来烫手即可&#xff0c;用刀片翘起后盖 注意&#xff1a;要从上下边缘翘&#xff0c;不要伤到侧键排线&#xff0c;侧键排线在左侧边缘靠上的位置&#xff08;手机屏幕朝下&#xff09;&…

CKA 基础操作教程(二)

Kubernetes Deployment 理论学习 Kubernetes Deployment &#xff08;部署&#xff09;是一种 Kubernetes 资源对象&#xff0c;用于定义和管理容器化应用程序的部署和更新。Deployment 提供了一种声明性的方式来定义应用程序的期望状态&#xff0c;并负责确保所需数量的 Pod…

【计算机毕业设计】校园论坛系统——后附系统源码

&#x1f389;**欢迎来到琛哥的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 琛哥&#xff0c;一名来自世界500强的资深程序猿&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 琛哥在深度学习任务中展现出卓越的能力&a…

Open CASCADE学习|平面上的PCurve

曲面上的曲线PCurve&#xff0c;字面上理解即为参数曲线(Parametric Curve)。在几何建模中&#xff0c;PCurve通常被描述为附加在参数曲面之间公共边上的数据结构。从更具体的定义来看&#xff0c;当给定一个曲面方程&#xff0c;并且其参数u和v是另一个参数t的函数时&#xff…

第8章 数据集成和互操作

思维导图 8.1 引言 数据集成和互操作(DII)描述了数据在不同数据存储、应用程序和组织这三者内部和之间进行移动和整合的相关过程。数据集成是将数据整合成物理的或虚拟的一致格式。数据互操作是多个系统之间进行通信的能力。数据集成和互操作的解决方案提供了大多数组织所依赖的…

Dubbo 服务发现

Dubbo 服务发现 1、什么是服务发现 **服务发现&#xff08;Service discovery&#xff09;**是自动检测一个计算机网络内的设备及其提供的服务。 2、Dubbo 与 服务发现 Dubbo 提供的是一种 Client-Based 的服务发现机制&#xff0c;依赖第三方注册中心组件来协调服务发现过…

【Web】纯萌新的BUUCTF刷题日记Day1

目录 [RoarCTF 2019]Easy Java [网鼎杯 2018]Fakebook [CISCN2019 华北赛区 Day2 Web1]Hack World [BJDCTF2020]The mystery of ip [网鼎杯 2020 朱雀组]phpweb [BSidesCF 2020]Had a bad day [BJDCTF2020]ZJCTF&#xff0c;不过如此 [BUUCTF 2018]Online Tool [GXYCTF…

面试算法-153-旋转图像

题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,…

20240408在全志H3平台的Nano Pi NEO CORE开发板的eMMC刷Ubuntu Core 16.04

20240408在全志H3平台的Nano Pi NEO CORE开发板的eMMC刷Ubuntu Core 16.04 2024/4/8 20:46 参考资料&#xff1a; https://wiki.friendlyelec.com/wiki/index.php/NanoPi_NEO_Core/zh#.E5.AE.89.E8.A3.85.E7.B3.BB.E7.BB.9F [ OK ] Created slice Slice /system/getty. [ …