详析STL之容器set

news/2024/10/28 9:27:19/

前言:今天我们来分享STL标准库容器set

关联式容器和序列式容器

序列式容器:我们学过的vector list deque forward_list都是序列式容器,底层都是线性的数据结果,存储的都是元素本身

关联式容器:存储的是的结构,在数据的搜索方便比序列式容器效率高

二者的区别:

(1)关联式容器是按关键字进行存储和访问的,而序列式容器是按元素在容器中的位置进行顺序存储和访问的
(2)关联式容器元素是按key值进行排序的(默认是升序),序列式容器按元素插入顺序进行排序
(3)序列式容器支持随机访问,关联式容器不支持随机访问,但是提供高效的查找功能,set是通过key进行快速的查找元素

键值对

表示一种一一对应的一种结构,该结构中一般包含两个成员变量(key,value),key表示键值,value表示与key对应的信息;举个例子,现在有一个英汉互译的软件,那么该软件中的英语单词必然有一个对应的汉语含义,所以通过该英语单词我们就可以找到该中文,这个就是键值对。

我们先来看看文档是如何介绍set容器的

在这里插入图片描述
那么文档里面说的是什么呢?

1.set是按照一定次数存储元素的容器(set默认按升序的规则进行排序)

2.在set只有一个value,value就是key,类型是T,并且每一个value都是唯一的。

3.在内部,集合中的元素总是按照其内部比较对象所指示的特定的严格弱排序标准进行排序

4.set容器通过key访问元素效率吗比unordered_set慢,

5.set底层是二叉搜索树(红黑树)

set的使用

set使用首选需要展开STL库和包头文件

#include <set>
using namespace std;

set的模板参数列表

在这里插入图片描述

set定义

set<类型名> 变量名;

set里面类型可以是任意的类型

set只能用双向迭代器进行访问(范围for底层也是迭代器)

	//迭代器遍历set<int>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;

在这里插入图片描述

set范围for遍历

我们知道范围fior底层是由迭代器支持的

//范围for遍历
for (auto kv : s)
{cout << kv << " ";
}
cout << endl;

在这里插入图片描述

set常用的成员函数接口

set插入数据

void test_set()
{//插入数据set<int> s;s.insert(3);s.insert(1);s.insert(2);s.insert(5);s.insert(4);
}

我们再来看看set里面数据能不能修改和set插入相同的数据会怎么样
在这里插入图片描述
直接就报错了,所以set里面的数据是不能修改的
我们看看插入相同数据会怎么样

void test_set()
{//插入数据set<int> s;s.insert(3);s.insert(1);s.insert(2);s.insert(5);s.insert(4);s.insert(4);s.insert(5);s.insert(3);//迭代器遍历set<int>::iterator it = s.begin();while (it != s.end()){cout << *it << " ";++it;}cout << endl;
}

在这里插入图片描述
正常运行,只是相同数据只会输出一次。

set交换元素

set<类型名>类型只能和set<类型名>类型的对象进行交换元素,必须是相同类型
在这里插入图片描述

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);set<int> s2;s2.insert(6);s2.insert(10);s2.insert(8);s2.insert(9);s2.insert(7);//范围for遍历for (auto kv : s1){cout << "s1:" << kv << " ";}cout << endl;for (auto kv : s2){cout << "s2:" << kv << " ";}cout << endl;//表示把s1中元素和s2的元素进行交换s1.swap(s2);//范围for遍历for (auto kv : s1){cout <<"s1:"<< kv << " ";}cout << endl;for (auto kv : s2){cout <<"s2:"<< kv << " ";}cout << endl;
}

在这里插入图片描述
不同类型进行交换元素

	{//插入数据set<int> s1;s1.insert(3);set<string> s2;s2.insert("6");
}

在这里插入图片描述

判断set是否为空

在这里插入图片描述
在这里插入图片描述
如果为空返回true,不为空返回false

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);cout << s1.empty() << endl;
}

在这里插入图片描述

返回set中有效元素

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);cout << s1.size() << endl;
}

在这里插入图片描述

统计set中值为x的元素个数

只要是在set中的元素,只会出现一次,利用这个性质,可以使用set进行去掉重复的数据

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);//查找s1中值为4的元素个数int count = s1.count(4);cout << count << endl;
}

在这里插入图片描述

set中key的查找

find查找元素 ,找到了就返回该元素的位置(返回类型是一个iterator类型),找不到返回一个指向end()的迭代器(end()是指向最后一个key的下一个位置)
在这里插入图片描述
在这里插入图片描述
set查找元素返回的是该元素所在的位置

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);//查找元素1所在的位置auto e = s1.find(1);cout << *e << endl;
}

在这里插入图片描述

set删除元素

erase通过迭代器删除单个元素,找到了就删除该元素,并返回被删除的元素的下一个元素的位置
erase 通过键值进行删除元素,如果删除成功返回1,删除失败返回0
erase删除一个范围内的元素,删除成功返回被删除元素的最后一个元素的下一个元素的位置
在这里插入图片描述

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);s1.erase(3);//范围for遍历for (auto kv : s1){cout << kv << " ";}
}

在这里插入图片描述

set元素清空

void test_set()
{//插入数据set<int> s1;s1.insert(3);s1.insert(1);s1.insert(2);s1.insert(5);s1.insert(4);s1.insert(4);s1.insert(5);s1.insert(3);s1.clear();//范围for遍历for (auto kv : s1){cout << kv << " ";}
}

在这里插入图片描述

总结:

这篇博客分享了关联容器和序列容器区别,还有键值对定义,还有set容器特点和和set容器的使用


http://www.ppmy.cn/news/1542560.html

相关文章

Java面试题库——Hibernate框架

1.为什么使用hibernate框架&#xff1f; 对JDBC访问数据库的代码做了封装&#xff0c;大大简化了数据访问层繁琐的重复性代码。 基于JDBC的主流持久性框架&#xff0c;是一个优秀的ORM实现&#xff0c;很大程度上的简化了dao层的编码工作。 使用java的反射机制。 性能好&#…

MySQL IN子句:数据顺序与条件顺序不一致情况探究(二)

2. 临时表/派生表的使用 另一个常见的方法是使用一个临时表或派生表&#xff08;也称为子查询&#xff09;来存储IN子句中的 ID&#xff0c;并为这些 ID 添加一个序号&#xff0c;然后在外层查询中根据这个序号进行排序。 使用示例&#xff1a; -- 新建临时表 CTE WITH Rout…

Python画图|极坐标下的柱状图输出

【1】引言 前序学习了极坐标下的散点图输出&#xff0c;可通过下述链接直达&#xff1a; 西猫雷婶-CSDN博客 受此启发&#xff0c;我们继续自主探索极坐标下的柱状图输出。 【2】代码探索 其实柱状图和散点图画图的主要区别&#xff0c;可以理解为调用函数不同。 柱状图调…

蓝桥杯普及题

[蓝桥杯 2024 省 B] 好数 题目描述 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。 给定一个正整数 N N N,请计算从 1 1

(三)第一个Qt程序“Qt版本的HelloWorld”

一、随记 我们在学习编程语言的时候&#xff0c;各种讲解编程语言的书籍中通常都会以一个非常经典的“HelloWorld”程序展开详细讲解。程序虽然简短&#xff0c;但是“麻雀虽小&#xff0c;五脏俱全”&#xff0c;但是却非常适合用来熟悉程序结构、规范&#xff0c;快速形成对编…

Js 中迭代器、生成器详解!

序言 什么是 迭代器? 广义上来讲 迭代器 (iterator) 有时又称光标 (cursor) 是程序设计软件的一种 设计模式, 可在 容器对象 (container, 例如例如列表、元组或字典) 上遍访的接口, 开发者无需关心容器对象的实现细节, 就可以通过它按照 特定的顺序 访问其中的每个元素, 同时…

Java学习Day51:紫云山金丹培育基地(移动端开发之多表联查,发送短信验证码)

移动端开发主要有三种方式&#xff1a; 1、基于手机API开发&#xff08;原生APP&#xff09; 2、基于手机浏览器开发&#xff08;移动web&#xff09; 3、混合开发&#xff08;混合APP&#xff09; 1.发送短信验证码 <dependency><groupId>com.aliyun</gro…

Flink 状态精准一次性特性

Flink 的一个重大价值在于&#xff0c; 它既保证了 exactly-once &#xff0c;也具有低延迟和高吞吐 的处理能力 。 1.端到端&#xff08;End-To-End&#xff09;状态一致性 端到端的一致性保证&#xff0c;意味着结果的正确性贯穿了整个流处理应用的始终&#xff1b;每 一…