容器库(6)-std::set

news2024/11/15 9:06:18

std::set是以key为元素的关联容器,容器中的key是唯一的且按顺序排列的。搜索、移除和插入的时间复杂度是 O(logn)。底层通常是以红黑树实现的。

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<Key>
> class set;

本文章的代码库:

https://gitee.com/gamestorm577/CppStd

成员函数

构造、析构和赋值

构造函数

可以用迭代器、另一个set或者元素列表来构造一个set。代码示例:

auto print_func = [](const std::set<int>& set)
{
    for (auto i : set)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<int> vec{11, 7, 5, 3, 5, 5, 11};

std::set<int> s1(vec.begin(), vec.end());
std::set<int> s2(s1);
std::set<int> s3{29, 15, 15, 3, 17};

print_func(s1);
print_func(s2);
print_func(s3);

输出结果:

3 5 7 11 
3 5 7 11 
3 15 17 29 

析构函数

删除set时,会调用各元素的析构函数。代码示例:

struct MyStruct
{
    MyStruct(int i)
        : Index(i)
    {
    }

    ~MyStruct()
    {
        std::cout << "destruct, Index = " << Index << std::endl;
    }

    int Index = 0;
};

struct MyStructCmp
{
    bool operator()(const MyStruct& lhs, const MyStruct& rhs) const
    {
        return lhs.Index < rhs.Index;
    }
};

std::set<MyStruct, MyStructCmp> s = {7, 3, 17, 3, 9};
std::cout << "end" << std::endl;

输出结果:

destruct, Index = 9
destruct, Index = 3
destruct, Index = 17
destruct, Index = 3
destruct, Index = 7
end
destruct, Index = 3
destruct, Index = 9
destruct, Index = 17
destruct, Index = 7

赋值函数

可以用另一个set或者元素列表给set赋值。代码示例:

std::set<int> tmp{29, 15, 15, 3, 17, 17, 19};
std::set<int> s1;
std::set<int> s2;
s1 = tmp;
s2 = {29, 15, 15, 3, 17, 17, 19};
std::cout << "s1 size = " << s1.size() << std::endl;
std::cout << "s2 size = " << s2.size() << std::endl;

输出结果:

s1 size = 5
s2 size = 5

迭代器

接口begin、cbegin指向list起始的迭代器,end、cend指向末尾的迭代器。rbegin、crbegin指向起始的逆向迭代器,rend、crend指向末尾的逆向迭代器。无论什么迭代器都不能修改元素的值。代码示例:

std::set<int> s{7, 15, 19, 29, 39};
for (auto iter = s.begin(); iter != s.end(); ++iter)
{
    std::cout << "num is: " << *iter << std::endl;
}

输出结果:

num is: 7
num is: 15
num is: 19
num is: 29
num is: 39

容量

empty

检查set是否为空。代码示例:

std::set<int> s1{7, 15, 19, 29, 39};
std::set<int> s2;
std::cout << std::boolalpha;
std::cout << "s1 empty: " << s1.empty() << std::endl;
std::cout << "s2 empty: " << s2.empty() << std::endl;

输出结果:

s1 empty: false
s2 empty: true

size

获取set中元素的个数。代码示例:

std::set<int> s1{7, 15, 19, 29, 39};
std::set<int> s2;
std::cout << "s1 size = " << s1.size() << std::endl;
std::cout << "s2 size = " << s2.size() << std::endl;

输出结果:

s1 size = 5
s2 size = 0

max_size

返回可以容纳的最大元素个数。代码示例:

struct MyStruct
{
    double num1;
    double num2;
    double num3;
    double num4;
};

std::set<float> s1;
std::set<double> s2;
std::set<MyStruct> s3;
std::cout << "s1 max size = " << s1.max_size() << std::endl;
std::cout << "s2 max size = " << s2.max_size() << std::endl;
std::cout << "s3 max size = " << s3.max_size() << std::endl;

输出结果:

s1 max size = 576460752303423487
s2 max size = 461168601842738790
s3 max size = 288230376151711743

修改器

clear

清除所有的元素。代码示例:

std::set<int> s{7, 15, 19, 29, 39};
std::cout << "s size = " << s.size() << std::endl;
s.clear();
std::cout << "s size = " << s.size() << std::endl;

输出结果:

s size = 5
s size = 0

extract

提取一个元素并返回它的句柄,提取完成后set不再拥有该元素。代码示例:

auto print_func = [](const std::set<int>& set)
{
    for (auto i : set)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::set<int> s{1, 2, 3};
print_func(s);
std::set<int>::node_type node = s.extract(1);
print_func(s);

std::cout << std::boolalpha;
std::cout << "node empty: " << node.empty() << std::endl;
std::cout << "node value: " << node.value() << std::endl;
node.value() = 5;
std::cout << "node value: " << node.value() << std::endl;

insert

插入元素,可以插入元素、迭代器或者节点。代码示例:

auto print_func = [](const std::set<int>& set)
{
    for (auto i : set)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<int> vec{7, 8, 9};

std::set<int> s{2, 3, 5, 7, 11};
print_func(s);

s.insert(4);
print_func(s);
s.insert(4);
print_func(s);

s.insert(std::next(s.begin(), 1), 19);
print_func(s);

s.insert(vec.begin(), vec.end());
print_func(s);

std::set<int>::node_type node = s.extract(19);
print_func(s);
node.value() = 1;
s.insert(std::move(node));
print_func(s);

输出结果:

2 3 5 7 11 
2 3 4 5 7 11 
2 3 4 5 7 11 
2 3 4 5 7 11 19 
2 3 4 5 7 8 9 11 19 
2 3 4 5 7 8 9 11 
1 2 3 4 5 7 8 9 11 

emplace

构造一个元素到set中。代码示例:

struct MyStruct
{
    MyStruct(float num1, int num2)
    {
        std::cout << "construct " << num1 << " " << num2 << std::endl;
    }
};

struct MyStructCmp
{
    bool operator()(const MyStruct&, const MyStruct&) const
    {
        return true;
    }
};

std::set<MyStruct, MyStructCmp> s;
s.emplace(1.5f, 2);
s.emplace(12.1f, 9);

输出结果:

construct 1.5 2
construct 12.1 9

erase

移除指定位置的元素或者移除指定的值。代码示例:

auto print_func = [](const std::set<int>& set)
{
    for (auto i : set)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::set<int> s{1, 2, 3, 4, 5, 6, 7, 8, 9};
print_func(s);
s.erase(std::next(s.begin(), 2));
print_func(s);
s.erase(std::next(s.begin(), 2), std::next(s.begin(), 5));
print_func(s);
s.erase(8);
print_func(s);

输出结果:

1 2 3 4 5 6 7 8 9 
1 2 4 5 6 7 8 9 
1 2 7 8 9 
1 2 7 9 

swap

和另一个set交换元素内容。代码示例:

std::set<int> s1{1, 2, 3, 4, 5, 6, 7, 8, 9};
std::set<int> s2{1, 2, 3};
s1.swap(s2);
std::cout << "s1 size = " << s1.size() << std::endl;
std::cout << "s2 size = " << s2.size() << std::endl;

输出结果:

s1 size = 3
s2 size = 9

merge

合并另一个set或者multiset的元素。代码示例:

auto print_func = [](std::string tag, const std::set<int>& set)
{
    std::cout << tag;
    for (auto i : set)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::set<int> s1{1, 2, 8, 9};
std::set<int> s2{3, 4};
s1.merge(s2);
print_func("s1 = ", s1);
print_func("s2 = ", s2);

输出结果:

s1 = 1 2 3 4 8 9 
s2 = 

查找

count

获取元素的数量。由于set的元素是不重复的,结果只能是0或者1。代码示例:

std::set<int> s{1, 2, 8, 9};
std::cout << "elment 1 count = " << s.count(1) << std::endl;
std::cout << "elment 3 count = " << s.count(3) << std::endl;

输出结果:

elment 1 count = 1
elment 3 count = 0

find

获取元素的位置。代码示例:

std::set<int> s{1, 2, 8, 9};
auto iter1 = s.find(1);
auto iter2 = s.find(3);

std::cout << std::boolalpha;
std::cout << "elment has 1: " << (iter1 == s.end()) << std::endl;
std::cout << "elment has 3: " << (iter2 == s.end()) << std::endl;

输出结果:

elment has 1: false
elment has 3: true

contains

检查是否包含特定的元素。代码示例:

std::set<int> s{1, 2, 8, 9};
std::cout << std::boolalpha;
std::cout << "contain 1: " << s.contains(1) << std::endl;
std::cout << "contain 3: " << s.contains(3) << std::endl;

输出结果:

contain 1: true
contain 3: false

equal_range

返回两个迭代器,第一个迭代器指向第一个大于等于指定元素的位置,第一个迭代器指向第一个大于指定元素的位置。代码示例:

std::set<int> s{2, 3, 5, 7, 11};
auto [iter1, iter2] = s.equal_range(3);
std::cout << "iter1 is: " << *iter1 << std::endl;
std::cout << "iter2 is: " << *iter2 << std::endl;
auto [iter3, iter4] = s.equal_range(4);
std::cout << "iter3 is: " << *iter3 << std::endl;
std::cout << "iter4 is: " << *iter4 << std::endl;
iter1 is: 3
iter2 is: 5
iter3 is: 5
iter4 is: 5

lower_bound

获取首个大于等于指定元素的位置。代码示例:

std::set<int> s{2, 3, 5, 7, 11};
auto iter1 = s.lower_bound(3);
auto iter2 = s.lower_bound(4);
std::cout << "iter1 is: " << *iter1 << std::endl;
std::cout << "iter2 is: " << *iter2 << std::endl;

输出结果:

iter1 is: 3
iter2 is: 5

upper_bound

获取首个大于指定元素的位置。代码示例:

std::set<int> s{2, 3, 5, 7, 11};
auto iter1 = s.upper_bound(3);
auto iter2 = s.upper_bound(4);
std::cout << "iter1 is: " << *iter1 << std::endl;
std::cout << "iter2 is: " << *iter2 << std::endl;

输出结果:

iter1 is: 5
iter2 is: 5

观察器

key_comp

返回用于比较键值的函数。代码示例:

struct Comp
{
    bool operator()(int lhs, int rhs) const
    {
        std::cout << "Comp" << std::endl;
        return lhs < rhs;
    }
};

std::set<int, Comp> s;
auto comp_func = s.key_comp();
std::cout << std::boolalpha;
std::cout << comp_func(10, 20) << std::endl;

输出结果:

Comp
true

value_comp

和key_comp相同,返回用于比较键值的函数。

非成员函数

比较运算符

operator==,!=,<,<=,>,>=用于比较两个set。代码示例:

std::set<int> s1 = {2, 3, 5};
std::set<int> s2 = {5, 3, 2};
std::cout << std::boolalpha;
std::cout << "s1 == s2: " << (s1 == s2) << std::endl;
std::cout << "s1 != s2: " << (s1 != s2) << std::endl;
std::cout << "s1 <  s2: " << (s1 < s2) << std::endl;
std::cout << "s1 <= s2: " << (s1 <= s2) << std::endl;
std::cout << "s1 >  s2: " << (s1 > s2) << std::endl;
std::cout << "s1 >= s2: " << (s1 >= s2) << std::endl;

输出结果:

s1 == s2: true
s1 != s2: false
s1 <  s2: false
s1 <= s2: true
s1 >  s2: false
s1 >= s2: true

swap

交换两个set的元素内容。示例代码:

std::set<int> s1 = {2, 3, 5};
std::set<int> s2 = {5, 3, 2, 19};
std::swap(s1, s2);
std::cout << "s1 size is: " << s1.size() << std::endl;
std::cout << "s2 size is: " << s2.size() << std::endl;

输出结果:

s1 size is: 4
s2 size is: 3

erase_if

删除满足条件的元素。代码示例:

std::set<int> s = {2, 3, 5, 7, 11, 13, 17};
std::cout << "s size = " << s.size() << std::endl;
std::erase_if(s,
              [](int a)
              {
                  return a > 11;
              });
std::cout << "s size = " << s.size() << std::endl;

输出结果:

s size = 7
s size = 5

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

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

相关文章

华为配置内部人员接入WLAN网络示例(802.1X认证)

配置内部人员接入WLAN网络示例&#xff08;802.1X认证&#xff09; 组网图形 图1 配置802.1X认证组网图 业务需求组网需求数据规划配置思路配置注意事项操作步骤配置文件 业务需求 用户接入WLAN网络&#xff0c;使用802.1X客户端进行认证&#xff0c;输入正确的用户名和密…

背包问题(01背包、完全背包、多重背包)详解(超详细!!!),及题目代码和题意,包含6个例题。

第一题&#xff1a;01背包问题 01背包问题 时间限制&#xff1a;1秒 内存限制&#xff1a;128M 题目描述 一个旅行者有一个最多能装 M 公斤的背包&#xff0c;现在有 n 件物品&#xff0c;它们的重量分别是 W1&#xff0c;W2&#xff0c;...,Wn ,它们的价值分别为 C1…

Netty的常用组件及线程模型设计(一)

Netty常用组件 Bootstrap Bootstrap是Netty框架的启动类和主入口类&#xff0c;发呢为客户端类Bootstrap和服务器类ServerBootstrap两种 Channel Channel是JavaNIO的一个基本构造&#xff0c;它代表一个到实体(如一个硬件设备、一个文件、一个网络套接字或者一个能够执行一…

电缆线的阻抗50Ω,真正含义是什么?

当我们提到电缆线的阻抗时&#xff0c;它到底是什么意思&#xff1f;RG58电缆通常指的是50Ω的电缆线。它的真正含义是什么&#xff1f;假如取一段3英尺(0.9144米)长的RG58电缆线&#xff0c;并且在前端测量信号路径与返回路径之间的阻抗。那么测得的阻抗是多少&#xff1f;当然…

探索C语言中的联合体与枚举:数据多面手的完美组合!

​ ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 联合体的定义 联合体又叫共用体&#xff0c;它是一种特殊的数据类型&…

Flomesh 发布 Pipy 0.99.1

值此新春佳节来临之际 &#xff0c;我们很高兴地宣布 Pipy 0.99.1 版本 的发布&#xff0c;此次更新带来了多项重要特性和改进&#xff0c;进一步增强了 Pipy 的功能性和灵活性。 新特性与改进&#xff1a; 增加了对 BPF (Berkeley Packet Filter) 的支持&#xff0c;包括加载…

Webstorm安装了vue脚手架后终端输入vue报错解决方法

当我们初学Vue的时候&#xff0c;刚安装完Vue脚手架之后&#xff0c;输入vue报错&#xff0c;是因为webstorm终端受限制了。 vue: 无法加载文件 C:\Users\Administrator\AppData\Roaming\npm\vue.ps1&#xff0c;因为在此系统上禁止运行脚本。 解决方案如下&#xff1a; 通过…

51单片机之数码管显示表白数字篇

朝菌不知晦朔 蟪蛄不知春秋 眼界决定境界 CSDN 请求进入专栏 是否进入《51单片机专栏》? 确定 目录 数码管的简介 数码管引脚定义 数码管的原理图 74HC245 代码实现 静态数码管的显示 动态数码管的显示 数码管实现表白画面 数码管的简介 L…

【Unity】重力场中的路径预测方法

前言 笔者前些天参加完了一场72小时的GameJam游戏开发比赛。这次比赛的主题是“探索”&#xff0c;笔者做了一个名为《探索者号》的探索宇宙的游戏&#xff08;游戏名一开始叫做《星际拾荒者》&#xff0c;但这不重要&#xff09;。 在开发过程中&#xff0c;笔者遇到了一些问…

2 月 7 日算法练习- 数据结构-并查集

并查集 并查集是一种图形数据结构&#xff0c;用于存储图中结点的连通关系。 每个结点有一个父亲&#xff0c;可以理解为“一只伸出去的手”&#xff0c;会指向另外一个点&#xff0c;初始时指向自己。 一个点的根节点是该点的父亲的父亲的的父亲&#xff0c;直到某个点的父亲…

探索NLP中的N-grams:理解,应用与优化

简介 n-gram[1] 是文本文档中 n 个连续项目的集合&#xff0c;其中可能包括单词、数字、符号和标点符号。 N-gram 模型在许多与单词序列相关的文本分析应用中非常有用&#xff0c;例如情感分析、文本分类和文本生成。 N-gram 建模是用于将文本从非结构化格式转换为结构化格式的…

Elasticsearch(四)

是这样的前面的几篇笔记&#xff0c;感觉对我没有形成知识体系&#xff0c;感觉乱糟糟的&#xff0c;只是大概的了解了一些基础知识&#xff0c;仅此而已&#xff0c;而且对于这技术栈的学习也是为了在后面的java开发使用&#xff0c;但是这里的API学的感觉有点乱&#xff01;然…

[VulnHub靶机渗透] dpwwn: 1

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏…

接口测试--参数实现MD5加密签名规则

最近有个测试接口需求&#xff0c;接口有签名检查&#xff0c;签名规范为将所有请求参数按照key字典排序并连接起来进行md5加密&#xff0c;格式是&#xff1a;md5(bar2&baz3&foo1),得到签名&#xff0c;将签名追加到参数末尾。由于需要对参数进行动态加密并且做压力测…

有道ai写作,突破免费限制,无限制使用

预览效果 文末提供源码包及apk下载地址有道ai写作python版 import hashlib import time import json import ssl import base64 import uuidfrom urllib.parse import quote import requests from requests_toolbelt.multipart.encoder import MultipartEncoder from Crypto.C…

11 串口发送应用之使用状态机实现多字节数据发送

1. 使用串口发送5个字节数据到电脑 uart协议规定&#xff0c;发送的数据位只能是6&#xff0c;7&#xff0c;8位&#xff0c;如果数据位不符合&#xff0c;接收者接收不到数据。所以我们需要将40位数据data分为5个字节数据分别发送&#xff0c;那么接收者就能通过uart协议接收…

Mobile ALOHA 2: An Enhanced Low-Cost Hardware for Bimanual Teleoperation

文章目录 1. Mobile ALOHA 11.1 项目地址 2. Mobile ALOHA 22.1 相关链接2.2 Whats upgraded in II ? Reference Stanford 最新家务机器人 1. Mobile ALOHA 1 Mobile ALOHA: Learning Bimanual Mobile Manipulation with Low-Cost Whole-Body Teleoperation 1.1 项目地址 htt…

CoreSight学习笔记

文章目录 1 Components1.1 ROM Table 2 使用场景2.1 Debug Monitor中断2.1.1 参考资料 2.2 Programming the cross halt2.2.1 编程实现2.2.2 参考资料 2.3 CTI中断2.3.1 编程实现2.3.1.1 准备工作2.3.1.2 触发中断2.3.1.3 中断响应 2.3.2 参考资料 1 Components 1.1 ROM Table…

力扣热门100题 - 4.寻找两个正序数组的中位数

力扣热门100题 - 4.寻找两个正序数组的中位数 题目描述&#xff1a;示例&#xff1a;提示&#xff1a;解题思路&#xff1a;代码&#xff1a; 题目链接&#xff1a;4.寻找两个正序数组的中位数 题目描述&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&a…

【golang】23、gorilla websocket 源码:examples、数据结构、流程

文章目录 一、examples1.1 echo1.1.1 server.go1.1.2 client.go 1.2 command1.2.1 功能和启动方式1.2.2 home.html1.2.3 main.go 1.3 filewatch1.3.1 html1.3.2 serveHome 渲染模板1.3.3 serveWs1.3.4 writer() 1.4 buffer pool1.4.1 server1.4.2 client 1.5 chat1.5.1 server1…