当前位置: 首页 > news >正文

C++(初阶)(十六)——set

set

  • set
    • set介绍
    • set的构造和迭代器
    • set的增删查
      • find
      • lower_bound
      • multiset和set的差异
    • 题目
      • [349. 两个数组的交集 - 力扣(LeetCode)](https://leetcode.cn/problems/intersection-of-two-arrays/description/)
      • 交集
      • 差集
      • [142. 环形链表 II - 力扣(LeetCode)](https://leetcode.cn/problems/linked-list-cycle-ii/description/)

set介绍

1,set的声明如下,T就是set底层关键字的类型

2,set默认要求T⽀持⼩于⽐较,如果不⽀持或者想按⾃⼰的需求⾛可以⾃⾏实现仿函数传给第⼆个模版参数

3,set底层存储数据的内存是从空间配置器申请的,如果需要可以⾃⼰实现内存池,传给第三个参 数。

4,⼀般情况下,我们都不需要传后两个模版参数。

5,set底层是⽤红⿊树实现,增删查效率是O(logN) ,迭代器遍历是⾛的搜索树的中序,所以是有序的。

6,前⾯部分我们已经学习了vector/list等容器的使⽤,STL容器接⼝设计,⾼度相似,所以这⾥我们 就不再⼀个接⼝⼀个接⼝的介绍,⽽是直接带着⼤家看⽂档,挑⽐较重要的接⼝进⾏介绍。

7,set是会去重的,所以删除数据时,没有使用bool值,而是int值。

set的构造和迭代器

set的⽀持正向和反向迭代遍历,遍历默认按升序顺序,因为底层是⼆叉搜索树,迭代器遍历⾛的中序;

⽀持迭代器就意味着⽀持范围for,set的iterator和const_iterator都不⽀持迭代器修改数据,修改 关键字数据,破坏了底层搜索树的结构。

// empty (1) 
⽆参默认构造explicit set (const key_compare& comp = key_compare(),const allocator_type& alloc = allocator_type());// range (2) 
迭代器区间构造template <class InputIterator>set (InputIterator first, InputIterator last,const key_compare& comp = key_compare(),const allocator_type& = allocator_type());// copy (3) 
拷⻉构造set (const set& x);// initializer list (5) initializer 
列表构造set (initializer_list<value_type> il,
const key_compare& comp = key_compare(),
const allocator_type& alloc = allocator_type());//迭代器是⼀个双向迭代器
//正向迭代器
iterator   -> a bidirectional iterator to const value_type
iterator begin();
iterator end();//反向迭代器
reverse_iterator rbegin();
reverse_iterator rend();

set的增删查

find

算法库中实现的查找是迭代器遍历,时间复杂度是O(n)

set内部实现的查找与树的高度有关,时间复杂度是O(logn)

count返回一个数据在set中的个数,但是set会去重,所以返回值是0或1,也是int值。

	set<int> s = { 2,3,1,7,1,1,5 };for (auto e : s){cout << e << " ";}cout << endl;//直接删除值为val的数据,不存在返回0s.erase(1);for (auto e : s){cout << e << " ";}cout << endl;//直接查找在利⽤迭代器删除valauto pos = s.find(3);if (pos != s.end()){s.erase(pos);}for (auto e : s){cout << e << " ";}cout << endl;//利⽤count间接实现快速查找int x = 7;if (s.count(x)){cout << x << "存在" << endl;}else{cout << x << "不存在" << endl;}

lower_bound

//返回⼤于等val位置的迭代器
iterator lower_bound (const value_type& val) const;

//返回⼤于val位置的迭代器
iterator upper_bound (const value_type& val) const;

算法库中也有lower_bound,upper_bound,但是要求是要对容器区间排序。
注意所得区间是左闭右开[lower,upper)

如果所给val > set.end();会返回set.end();的值

	set<int> myset = { 10,20,30,40,50,60,70,80,90 };for (auto e : myset){cout << e << " ";}cout << endl;//返回 >= 30位置的迭代器auto low = myset.lower_bound(30);//返回 > 70位置的迭代器,如果所给val > myset.end();会返回myset.end();的值auto up = myset.upper_bound(70);//使用迭代器打印[30,70)区间的值auto it = low;while (it != up){cout << *it << " ";++it;}cout << endl;//删除[30,70)区间的值myset.erase(low, up);for (auto e : myset){cout << e << " ";}cout << endl;

multiset和set的差异

使用multiset,头文件依然是#include< set >,不需要其他头文件

multiset不会进行去重操作。

在进行查找操作时,查找到数据是中序遍历的第一个数据。

题目

349. 两个数组的交集 - 力扣(LeetCode)

给定两个数组 nums1nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序

示例 1:

输入:nums1 = [1,2,2,1], nums2 = [2,2]
输出:[2]

示例 2:

输入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出:[9,4]
解释:[4,9] 也是可通过的

去重:unique(算法库中);set都可以

class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {// set<int> s1;// for(auto e : nums1)// {//     s1.insert(e);// }// set<int> s2;// for(auto e : nums2)// {  //     s2.insert(e);// }//迭代器区间构造比较方便set<int> s1(nums1.begin(),nums1.end());set<int> s2(nums2.begin(),nums2.end());vector<int> v;for(auto e : s1){//在set中count的返回值是1或0,如果s1中的数据在s2中也存在,就是交集if(s2.count(e)){v.push_back(e);}}return v;}
};

除此之外,还有方法能求交集,当然也可以带入求差集。

并集是直接遍历插入set< >即可,set< >会去重

交集

	vector<int> nums1 = { 1,3,5,6,7,8,9 };vector<int> nums2 = { 1,2,3,4,6 };vector<int> ret;//去重+排升序set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());//遍历比较auto it1 = s1.begin();auto it2 = s2.begin();while (it1 != s1.end() && it2 != s2.end()){if (*it1 < *it2){++it1;}else if (*it1 > *it2){++it2;}else{//ret.push_back(*it1);ret.push_back(*it2);++it1;++it2;}}for (auto e : ret){cout << e << " ";}cout << endl;

差集

	vector<int> nums1 = { 1,3,5,6,7,8,9 };vector<int> nums2 = { 1,2,3,4,6 };vector<int> ret;//去重+排升序set<int> s1(nums1.begin(), nums1.end());set<int> s2(nums2.begin(), nums2.end());//遍历比较auto it1 = s1.begin();auto it2 = s2.begin();while (it1 != s1.end() && it2 != s2.end()){if (*it1 < *it2){ret.push_back(*it1);++it1;}else if (*it1 > *it2){ret.push_back(*it2);++it2;}else{++it1;++it2;}}//剩余值继续记录while (it1 != s1.end()){ret.push_back(*it1);++it1;}while (it2 != s2.end()){ret.push_back(*it2);++it2;}for (auto e : ret){cout << e << " ";}cout << endl;

142. 环形链表 II - 力扣(LeetCode)

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos-1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

img

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

img

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

img

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode *detectCycle(ListNode *head) {set<ListNode*> s;ListNode* cur = head;while(cur){auto ret = s.insert(cur);if(ret.second == false)return cur;cur = cur->next;}return nullptr;}
};
http://www.xdnf.cn/news/231211.html

相关文章:

  • YOLO视觉模型可视化训练与推理测试工具
  • 嵌入式中常用的算法介绍
  • (Go Gin)Gin学习笔记(五)会话控制与参数验证:Cookie使用、Sessions使用、结构体验证参数、自定义验证参数
  • 自动驾驶-一位从业两年的独特视角
  • 2025年-redis(p1-p10)
  • Kotlin与Jetpack Compose的详细使用指南
  • 高级java每日一道面试题-2025年4月30日-基础篇[反射篇]-如何防止你的类被通过反射非法实例化?
  • PCI总线数据采集卡 32路多功能异步模拟量信号采集卡
  • 如何在 Go 中实现各种类型的链表?
  • 硬盘分区丢失≠末日!3步逻辑恢复法+物理修复全流程图解
  • 大数据应用开发和项目实战-Seaborn
  • 使用通义千问大模型做结构化输出报错的分析
  • ubantu部署yolov5(第四集:模型加速)
  • 正点原子STM32H743单片机实现ADC多通道检测
  • k8s平台:手动部署Grafana
  • SQL命令二:SQL 高级查询与特殊算法
  • Git从入门到精通-第一章-基础概念
  • 软件性能测试有多关键?能找出潜在问题并确保其顺利运行吗?
  • [250430] Kali Linux 存储库密钥丢失导致所有用户无法正常更新 APT
  • JavaScript:从JS的执行机制到location对象
  • 大语言模型(LLM)应用开发平台Dify详细使用
  • 系统思考:局部最优与全局失衡
  • WHAT - Tailwind CSS + Antd = MetisUI组件库
  • GEO vs SEO:从搜索引擎到生成引擎的优化新思路
  • vs2019 调试看不到std::list 中的值,
  • 上班无聊用python写一个摸鱼小游戏:数字碰撞
  • conda管理python环境
  • 2025年渗透测试面试题总结-拷打题库28(题目+回答)
  • 前端跨域问题详解:原因、解决方案与最佳实践
  • Doris索引机制全解析,如何用高效索引加速数据分析