【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 的元素,如果成功找到,则返回指向该元素的双向迭代器;反之,则返回和 end() 方法一样的迭代器。另外,如果 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.mzph.cn/news/792796.shtml

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

相关文章

Kotlin:for循环的几种示例

一、 打印 0 到 2 1.1 方式一&#xff1a;0 until 3 /*** 打印 0 到 2*/ fun print0To2M1(){for (inex in 0 until 3){// 不包含3print("$inex ")} }运行结果 1.2 方式二&#xff1a;inex in 0 …2 /*** 打印 0 到 2*/ fun print0To2M2(){for (inex in 0 ..2){//…

Go语言如何使用命令行程序

命令行程序也叫命令行实用程序或工具&#xff0c;它被设计在终端运行。 在图形用户界面面世前&#xff0c;与计算机交与通常是通过命令行进行的。当前&#xff0c;对程序员和系统管理员来说&#xff0c;命令行程序依然是一种流行而实用的与底层操作系统交互的方式。出于如下原因…

HarmonyOS NEXT应用开发之ForEach:循环渲染

ForEach接口基于数组类型数据来进行循环渲染&#xff0c;需要与容器组件配合使用&#xff0c;且接口返回的组件应当是允许包含在ForEach父容器组件中的子组件。例如&#xff0c;ListItem组件要求ForEach的父容器组件必须为 List组件 。 说明&#xff1a; 从API version 9开始&a…

Rust---复合数据类型之字符串与切片(1)

目录 字符串字符串与切片字符串切片字符串操作追加&#xff08;Push&#xff09;插入 (Insert)替换 (Replace) 字符串 Rust 在语言级别&#xff0c;只有一种字符串类型&#xff1a; str&#xff0c;它通常是以引用类型出现 &str。虽然语言级别只有上述的 str 类型&#xf…

C库函数详解(一)

库函数并不是C语言的一部分。它是由人们根据需要编制并提供用户使用的。每一种C编译系统都提供了一批库函数,不同的编译系统所提供的库函数的数目和函数名以及函数功能是不完全相同的。ANSIC标准提出了一批建议提供的标准库函数。它包括了目前多数C编译系统所提供的库函数,但也…

环形链表的约瑟夫问题

著名的 Josephus 问题&#xff1a; 据说著名犹太历史学家Josephus&#xff08;弗拉维奥约瑟夫斯&#xff09;有过以下的故事&#xff1a;在罗马人占领乔塔帕特后&#xff0c;39 个犹太人与Josephus及他的朋友躲到一个洞中&#xff0c;39个犹太人决定宁愿死也不要被敌人抓到&…

【哈希表专题】(1. 两数之和 面试题 01.02. 判定是否互为字符重排 217. 存在重复元素 219. 存在重复元素 II 49. 字母异位词分组)

文章目录 哈希表1. 两数之和面试题 01.02. 判定是否互为字符重排217. 存在重复元素219. 存在重复元素 II49. 字母异位词分组 哈希表 哈希表是什么&#xff1a;存储数据的容器 作用&#xff1a;快速查找某个元素。O(1) 当我们需要频繁的查找某一个数的时候&#xff0c;可以使…

LeetCode-Java:135.分发糖果

文章目录 题目解① 穷举法&#xff0c;用时3ms&#xff0c;超过26.93%②穷举法改进&#xff0c;用时2ms&#xff0c;超过97.78% 题目 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个…

图像拼接——最小割准则提取拼接缝

一、最大流问题与Ford-Fulkerson算法介绍 二、最大流与最小割 显然,我们有对任意一个割,穿过该割的净流量上界就是该割的容量,即不可能超过割的容量。所以网络的最大流必然无法超过网络的最小割。最小割是指割的容量最小,最大流是指网络当中最大的净流量,简单的例子s是水龙…

速盾:cdn高防御服务器租用有哪些好处

随着互联网的发展&#xff0c;网络安全问题日益突出。攻击者利用各种手段不断对网站进行攻击&#xff0c;给网站的安全运行带来威胁。为了保障网站的正常运行和数据的安全&#xff0c;越来越多的网站开始租用CDN高防御服务器。那么&#xff0c;租用CDN高防御服务器有哪些好处呢…

【蓝桥备赛】异或和——树状数组、DFS

题目链接 异或和 思路分析 树上每个点都有一个点权&#xff0c;对树上的更新操作是修改指定点的点权&#xff0c;查询操作是查询指定点为根结点的子树点权异或和。 这里的这些操作都和树状数组的单点修改和区间查询非常相似&#xff0c;即我们在修改一个点时&#xff0c;同时…

蓝桥杯真题:递增序列

import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class Main {public static int is1(char ch[][],int m,int n){int ans0;for (int i0;i<m;i){for (int j0;j<n;j){int add1;while(jadd<n){if(ch[i][j]<ch[i][jadd]) ans; //横…

SAP新的扩展策略

在软件即服务&#xff08;SaaS&#xff09;应用的推动下&#xff0c;SAP Cloud优先的战略非常明显&#xff0c;随之带来的是SAP Clean core的战略&#xff0c;从经典的 ABAP 可扩展性模式转变为 SAP S/4HANA 现代可扩展性模式。那么Clean core战略到底是什么&#xff1f;新的扩…

基于向量数据库搭建自己的搜索引擎

前言【基于chatbot】 厌倦了商业搜索引擎搜索引擎没完没了的广告&#xff0c;很多时候&#xff0c;只是需要精准高效地检索信息&#xff0c;而不是和商业广告“斗智斗勇”。以前主要是借助爬虫工具&#xff0c;而随着技术的进步&#xff0c;现在有了更多更方便的解决方案&…

LongAdder 和 Striped64 基础学习

cs&#xff0c;表示 Cell 数组的引用&#xff1b;b&#xff0c;表示获取的 base 值&#xff0c;类似于 AtomicLong 中全局变量的 value 值&#xff0c;在没有竞争的情况下数据直接累加到 base 上&#xff0c;或者扩容时&#xff0c;也需要将数据写入到 base 上&#xff1b;v&am…

Linux第2课Windows下的环境配置-虚拟机安装

文章目录 Linux第2课Windows下的环境配置-虚拟机安装一、VMware虚拟机的安装&#xff08;一&#xff09;安装VMware&#xff08;二&#xff09;启动电脑本地的VMware相关服务 二、VirtualBox安装 Linux第2课Windows下的环境配置-虚拟机安装 本节课程提供了两种虚拟机的安装方法…

个人医疗开支预测项目

注意&#xff1a;本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 &#xff08;[www.aideeplearning.cn]&#xff09; 项目背景 随着医疗成本的持续上涨&#xff0c;个人医疗开支成为一个重要议题。理解影响医疗费用的多种因素对于医疗保险公司、政府机构以及个人…

磁环的使用方法

磁环的使用方法 磁环的工作原理共模滤波用法差模滤波用法各种材料磁环的对应频率磁环的感量计算 磁环的工作原理 共模滤波用法 差模滤波用法 各种材料磁环的对应频率 磁环的感量计算

Redis从入门到精通(四)Redis实战(二)商户查询缓存

↑↑↑请在文章头部下载测试项目原代码↑↑↑ 文章目录 前言4.2 商户查询缓存4.2.1 缓存介绍4.2.2 查询商户信息的传统做法4.2.2.1 接口文档4.2.2.2 代码实现4.2.2.3 功能测试 4.2.3 查询商户信息添加Redis缓存4.2.3.1 逻辑分析4.2.3.2 代码实现4.2.3.3 功能测试 4.2.3 数据一致…

软考之零碎片段记录(五)

一、设计模式 1.策略模式 可在运行时改变行为和算法。这种类型的设计模式属于行为模式。使得代码更加灵活和可维护。 2. 命令模式 将请求封装成独立的对象并通过参数传递。属于行为模式。 3. 观察者模式 当对象状态改变时&#xff0c;依赖于它的对象都会被通知并进行更新…