STL--set和multiset集合

在这里插入图片描述


set和multiset会根据特定的排序准则,自动将元素排序。两者不同之处在于multiset 允许元素重复而 set 不允许。如下图:

在这里插入图片描述
使用set或multiset,必须先包含头文件:

#include <set>

上述两个类型都被定义为命名空间std内的class template:

namespace std {template <typename T,typename Compare = less<T>,typename Allocator = allocator<T> >class set;template <typename T,typename Compare = less<T>,typename Allocator = allocator<T> >class multiset;
}

其中T是能进行排序的数据类型。第二个参数是进行排序的规则,默认为升序(小于,<),第三个是内存分配器,不用管。

set 和multiset通常用平衡二叉树(balanced binary tree,确切说是红黑树)实现。这样在插入数据时能自动排序,使得查找元素时有良好性能。其查找函数具有对数O(logn)时间复杂度。

但是,自动排序也造成set和multiset的一个重要限制:你**不能直接改变元素值,**因为这样会打乱原本正确的顺序。

在这里插入图片描述
从其接口也能反映这种情况:

set和multiset不提供任何函数可以直接访问元素。

通过迭代器访问元素时都是常量。

1.1 定义及初始化🍗

set的定义和初始化如下:


#include <set>
#include <iostream>
using namespace std;//输出s(升序)的所有数据
void Show(const set<int>& s)
{for (auto i : s)cout << i << " ";cout << endl;
}//输出s(降序)的所有数据
void Show(const set<int,greater<int>>&s)
{for (auto i : s)cout << i << " ";cout << endl;
}int main()
{set <int> s0;//创建一个空的int set集合    s0.insert(5); //插入数据    s0.insert(3);    s0.insert(1);    s0.insert(2);    s0.insert(4);    s0.insert(4);//相同数据插入失败    set <int> s1(s0); //利用原来的set对象,创建一个新的set对象    set <int> s2 = s1;//同上    set <int> s3(s0.begin(), --s0.end());//利用迭代器创建一个新的set对象set <int> s4{  1, 6, 3, 5, 4, 2  };//利用初始化列表创建一个set对象,可以无序    cout << "s0:"; Show(s0); //输出数据    cout << "s1:"; Show(s1);    cout << "s2:"; Show(s2);    cout << "s3:"; Show(s3);    cout << "s4:"; Show(s4);    cout << "降序的集合" << endl;    set <int, greater<int> > s5; //创建一个降序的set集合    s5.insert(10);//插入数据    s5.insert(40);    s5.insert(30);    s5.insert(20);    cout << "s5:"; Show(s5);//输出数据    return 0;    
}

multiset定义和初始化如下:


#include <set>
#include <iostream>
using namespace std;//输出s(升序)的所有数据
void Show(const multiset<int>& s)
{for (auto i : s)cout << i << " ";cout << endl;
}//输出s(降序)的所有数据
void Show(const multiset<int, greater<int>>& s)
{for (auto i : s)cout << i << " ";cout << endl;
}int main()
{multiset <int> s0;//创建一个空的int set集合s0.insert(5); //插入数据s0.insert(3);s0.insert(1);s0.insert(2);s0.insert(4);s0.insert(4);//可以插入相同数据multiset <int> s1(s0); //利用原来的set对象,创建一个新的set对象multiset <int> s2 = s1;//同上multiset <int> s3(s0.begin(), --s0.end());//利用迭代器创建一个新的set对象multiset <int> s4{ { 1, 6, 3, 5, 4, 2 } };//利用初始化列表创建一个set对象cout << "s0:"; Show(s0); //输出数据cout << "s1:"; Show(s1);cout << "s2:"; Show(s2);cout << "s3:"; Show(s3);cout << "s4:"; Show(s4);cout << "降序的集合" << endl;multiset <int, greater<int> > s5; //创建一个降序的set集合s5.insert(10);//插入数据s5.insert(40);s5.insert(30);s5.insert(20);cout << "s5:"; Show(s5);//输出数据return 0;
}

1.2 向set和multiset中添加元素和删除元素🍗

通过insert函数插入数据。通过erase删除元素。


//输出s(升序)的所有数据
void Show(const set<int>& s)
{for (auto i : s)cout << i << " ";cout << endl;
}
int main()
{set<int> s1;s1.insert(4);s1.insert(1);s1.insert(5);s1.insert(2);cout << "s1:";  Show(s1);s1.erase(2);cout << "删除2后,s1:";  Show(s1);s1.clear();cout << "清空后,s1:";  Show(s1);return 0;
}

1.3 常用迭代器🍗

set和multiset支持双向迭代器,不支持随机迭代器,可以往前和往后,但不能+1,-1(这是随机迭代器)等。
常用的迭代器如下:
s.begin()
第一个元素的迭代器
s.end()
最后一个元素的下一个位置迭代器(尾后迭代器或尾迭代器)
s.cbegin()
第一个元素的常量迭代器(不修改元素内容)
s.cend()
尾后常量迭代器(不修改元素内容)
s.rbegin()
第一个反向迭代器
s.rend()
尾后反向迭代器

int main()    
{set<int> s1;    s1.insert(4);    s1.insert(1);    s1.insert(5);    s1.insert(2);    cout << "从头到尾输出s1:";    for (auto p = s1.begin(); p != s1.end(); p++)    cout << *p << " ";    cout << endl;    cout << "从后往前输出s1:";    for (auto p = s1.rbegin(); p != s1.rend(); p++)    cout << *p << " ";    cout << endl;    auto p = s1.begin();    cout << "第二个元素:"<< * (++p) << endl;//输出第二个元素    cout << "第一个元素:"<< * (--p) << endl;//输出第一个元素    //cout << *(p + 1) << endl;//错误    return 0;    
}

1.4 set和multiset常用的运算符🍗

set和multiset类既支持常用的=,==,!=,< , >等运算符,也可以通过调用其成员函数来执行相应的操作。下面列举了其常用的操作。详细情况可以参考set或multiset帮助手册。


//输出s(升序)的所有数据    
void Show(const set<int>& s)    
{for (auto i : s)    cout << i << " ";    cout << endl;    
}int main()    
{set<int> s1;    s1.insert(4);    s1.insert(1);    s1.insert(5);    s1.insert(2);    cout << "s1:";  Show(s1);    set<int> s2;    s2 = s1;    cout << "s2:";  Show(s2);    if (s1 == s2)    cout << "s1 == s2" << endl;    s2.insert(7);    cout << "往s2插入7后,";    if (s1 > s2)    cout << "s1 > s2" ;    else if (s1 < s2)    cout << "s1 < s2" ;    //cout << s1[1] << endl;//错误    return 0;    
}

1.5 set和multiset常用成员函数🍗

下面列举set和multiset对象常用的成员函数,详细的介绍请查看帮助手册。

在这里插入图片描述

1.6 set应用场景🍗

set在C++中是一个内部自动有序且不含重复元素的容器,它的应用场景广泛且多样。以下是一些set的常见应用场景:

1.自动排序
如果需要对元素保持持续的排序状态,如维持一个按字母顺序排列的单词列表、存储并维护一个按年龄升序或降序排列的人口数据库等,std::set 可以实现这一功能。每次插入新元素,容器都会自动调整元素的顺序。

当然如果仅仅是排序,可以使用sort函数进行排序.
sort排序是在排序瞬间的,如果又插入新的数据可能不再有序
set的有序是持续的,不管插入还是删除数据它始终有序

2.快速查找
由于set内部采用了高效的平衡查找二叉树(如红黑树),因此它提供快速的查找性能。包括检查元素是否已存在(.count() 或 .find())、查找特定值的下一个/前一个元素(迭代器操作)。这对于实现诸如查找词汇表中的下一个更大词、或者在游戏中查找排名高于当前玩家的下一个玩家等场景很有用。


本篇完!🍗

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

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

相关文章

亚马逊自养号测评:深入解析与搭建要求

在亚马逊这电商平台上&#xff0c;商品的评价对于卖家来说至关重要。为了提升商品的曝光率、排名、权重和销量&#xff0c;卖家们纷纷采用各种推广方式&#xff0c;其中&#xff0c;亚马逊自养号测评成为了越来越多卖家选择的一种有效方式。 亚马逊自养号测评&#xff0c;顾名…

分布式事务——9种解决方案的原理与分类

目录 一、概要1. 分布式事务的概念2. 分布式事务解决方案分类 二、常见的分布式事务解决方案1. 基础的 2PC&#xff08;二阶段提交&#xff09;1.1 核心思想1.2 简介1.3 主要特点1.3.1 优点1.3.2 缺点 2. 基础的 3PC&#xff08;三阶段提交&#xff09;2.1 核心思想2.2 简介2.3…

C语言/数据结构——每日一题(有效的括号)

一.前言 如果想要使用C语言来解决这道题——有效的括号&#xff1a;https://leetcode.cn/problems/valid-parentheses/description/我们必须要借用上一篇我们所讲的内容——栈的实现&#xff1a;https://blog.csdn.net/yiqingaa/article/details/138923750?spm1001.2014.3001.…

go routing 之 gorilla/mux

1. 背景 继续学习 go 2. 关于 routing 的学习 上一篇 go 用的库是&#xff1a;net/http &#xff0c;这次我们使用官方的库 github.com/gorilla/mux 来实现 routing。 3. demo示例 package mainimport ("fmt""net/http""github.com/gorilla/mux&…

react实现把pc网站快捷添加到桌面快捷方式

文章目录 1. 需求2. 实现效果3. 核心逻辑4. 完整react代码 1. 需求 这种需求其实在国外一些游戏网站和推广网站中经常会用到&#xff0c;目的是为了让客户 快捷方便的保存网站到桌面 &#xff0c;网站主动尽量避免下次找不到网站地址了&#xff0c;当然精确的客户自己也可以使…

Oracle递归查询笔记

目录 一、创建表结构和插入数据 二、查询所有子节点 三、查询所有父节点 四、查询指定节点的根节点 五、查询指定节点的递归路径 六、递归子类 七、递归父类 一、创建表结构和插入数据 CREATE TABLE "REGION" ( "ID" VARCHAR2(36) DEFAULT SYS_GUI…

GPT提示词技巧,使用教程,国内版官网直达,非套壳

GPT提示词技巧&#xff0c;使用教程&#xff0c;国内版官网直达&#xff0c;非套壳 主站点&#xff1a;https://chatgpt-plus.top&#xff08;江苏福建地区打不开&#xff0c;需要魔法&#xff09; 店铺地址&#xff1a;https://buy.chatgpt-plus.top/ 选择plus账号进入&…

鸿蒙开发ArkUI-X基础知识:【ArkUI代码工程及构建介绍】

代码工程及构建介绍 背景 ArkUI作为OpenHarmony的默认开发框架&#xff0c;在本项目&#xff08;ArkUI-X&#xff09;中需要做到一套代码同时支持多平台构建&#xff0c;所以会采取共仓开发的方式&#xff0c;部分仓直接指向OpenHarmony相关开源仓。 代码结构及仓库结构 代…

【机器学习300问】94、什么是多任务学习?

一、多任务学习的定义 多任务学习&#xff08;Multi-Task Learning, MTL&#xff09;是一种机器学习范式&#xff0c;它允许一个模型同时学习执行多个相关但不完全相同的任务。这种方法的核心是&#xff1a;通过共享表示或权重&#xff0c;不同的任务可以在学习过程中相互促进&…

Python中文件操作和异常处理

文章目录 一、文件操作1.概念2.文件3.二进制 二、基本文件操作三、乱码产生四、with open() as f五、代码实现文件复制粘贴六、try ... except ...七、代码比较 一、文件操作 1.概念 帮助我们把爬虫抓下来的数据&#xff0c;进行保存。 2.文件 在计算机中&#xff0c;没有p…

力扣226. 翻转二叉树(DFS的两种思路)

Problem: 226. 翻转二叉树 文章目录 题目描述思路复杂度Code 题目描述 思路 涉及二叉树的递归解法时往往需要考虑两种思路&#xff1a; 1.在递归遍历时执行题目需要的具体要求&#xff1b; 2.将一个大问题分解为多个小子问题 具体到本体&#xff1a; 思路1&#xff1a;遍历 先…

【源码分享】简单的404 HTML页面示例,该页面在加载时会等待2秒钟,然后自动重定向到首页

展示效果 源码 html <!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><title>404 页面未找到</title><meta http-equiv"refresh" content"2;url/"> <!-- 设置2秒后跳转到首…

机器学习云环境测试

等待创建完成后&#xff0c;点击 PyTorch 打开&#xff0c;创建一个全新的 notebook 在 Cell 中输入如下代码&#xff0c;并点击 Run 完成后点击 New Cell &#xff0c;在 New Cell 中输入如下代码 输入完成后点击 Run &#xff0c;运行 New Cell 。&#xff08;每个 Cell 代…

1077: 平衡二叉树的判定

解法&#xff1a; 平衡二叉树是一种特殊的二叉树&#xff0c;它满足以下两个条件&#xff1a; 左子树和右子树的高度差不超过1&#xff08;即&#xff0c;左右子树高度差的绝对值不超过1&#xff09;。左子树和右子树都是平衡二叉树。 后序遍历过程中每次判断左右子树高度差…

IT廉连看——UniApp——事件绑定

IT廉连看——UniApp——事件绑定 这是我们上节课最终的样式&#xff1b; 一、现在我有这样一个需求&#xff0c;当我点击“生在国旗下&#xff0c;长在春风里”它的颜色由红色变为蓝色&#xff0c;该怎么操作&#xff1f; 这时候我们需要一个事件的绑定&#xff0c;绑定一个单…

使用 Docker 部署 Jenkins 并设置初始管理员密码

使用 Docker 部署 Jenkins 并设置初始管理员密码 每一次开始&#xff0c;我都特别的认真与胆怯&#xff0c;是因为我期待结局&#xff0c;也能够不会那么粗糙&#xff0c;不会让我失望&#xff0c;所以&#xff0c;就多了些思考&#xff0c;多了些拘束&#xff0c;所以&#xf…

【HCIP学习】STP协议

一、STP协议出现背景&#xff08;Spanning Tree Protocol&#xff0c;生成树协议&#xff09; 二层环路带来的问题&#xff1a;广播风暴&#xff1b; MAC地址表的震荡&#xff1b; 二、STP定义 stp是二层网络中用于消除环路的协议&#xff0c;通过阻断冗余链路来消除&#xff…

加速度传感器的冲击振动的原始特征与解算(部分)

这里是工作中测得的一组数据&#xff0c;设备有多个加速度传感器通道&#xff0c;我们可以看到冲击振动发生前后&#xff0c;各个振动传感器的的反馈以及其他的细化特征&#xff1a; 1.随机振动&#xff08;加速度传感器视角&#xff09; 2.冲击振动&#xff08;加速度&#x…

C++ 网络编程

一、Reactor 网络编程模型 reactor 是一个事件处理模型。网络处理:因为用户层并不知道 IO 什么时候就绪,所以将对 IO 的处理转化为对事件的处理。网络模型构成: 非阻塞 IO:操作 IO,如果 IO 未就绪,IO 函数会立刻返回。IO 多路复用:检测多路 IO 是否就绪。工作流程: 注册…

【从零开始实现stm32无刷电机FOC】【理论】【1/6 电机旋转本质】

目录 电机旋转需要什么样的力&#xff1f;怎么产生力矢量&#xff1f;怎么产生任意的线圈磁矢量&#xff1f; 电机旋转需要什么样的力&#xff1f; 电机切向存在受力&#xff0c;电机就会旋转。 进一步查看电机结构&#xff0c;分为转子和定子&#xff0c;大部分情况下&#…