C++ set 常用部分

文章目录

关键特性

  • 唯一性 :Set容器内的元素都是唯一的 ,每个元素都是不同的
  • 有序性 :Set容器内的元素总是排序的(C++中默认升序),向Set中添加元素,将自动插入到正确的位置中,不需要手动排序
  • 查找/插入快速 :因为Set容器的元素是排序的,所以在Set中查找和插入元素都很快

定义及初始化

cpp 复制代码
#include <set>
set<Type> s;						      
set<int> s = {1,2,3,4,5};	 
vector<int> a = {1,2,3,4,5};
set<int> s(a.begin(),a.end());
set<Type> s(s1);			              //定义一个set容器,并用容器s1来初始化
set<Type> s(b, e);					  //b和e分别为迭代器的开始和结束的标记
set<Type> s(s1.begin(), s1.begin()+3); //用容器s1的第0个到第2个值初始化s
set<Type> s(a, a + 5);      		      //将a数组的元素初始化vec向量
set<Type> s(&a[1], &a[4]); 			  //将a[1]~a[4]范围内的元素作为s的初始值

一些基本操作

cpp 复制代码
s.begin();					//返回指向第一个元素的迭代器
s.end();					//返回指向最后一个元素的迭代器
s.clear();					//清除所有元素
s.count();					//返回某个值元素的个数
s.empty();					//如果集合为空,返回true,否则返回false
s.equal_range();			//返回集合中与给定值相等的上下限的两个迭代器
s.erase();					//删除集合中的元素
s.find(k);					//返回一个指向被查找到元素的迭代器
s.insert();					//在集合中插入元素
s.lower_bound(k);			//返回一个迭代器,指向键值大于等于k的第一个元素
s.upper_bound(k);			//返回一个迭代器,指向键值大于k的第一个元素
s.max_size();				//返回集合能容纳的元素的最大限值
s.rbegin();					//返回指向集合中最后一个元素的反向迭代器
s.rend();					//返回指向集合中第一个元素的反向迭代器
s.size();					//集合中元素的数目

查找

find(x)方法寻找带有特定键的元素,返回的是迭代器。

cpp 复制代码
set<int> s = {1,2,3,4,5};

if(s.find(3)!=s.end())//若存在,返回一个迭代器,指向键值;若不存在,返回一个迭代器,指向s.end()。
	cout<<*s.find(3)<<endl;
else
    cout<<"NOT FOUND"<<endl;

count(x)方法返回的是set中元素x的个数。由于个数只能是0或1,所以当返回值非0时表示元素在集合中,反之不在。

cpp 复制代码
set<int> s = {1,2,3,4,5};

if(s.count(3) > 0)
    cout << s.count(3) << endl;
else
    cout<<"NOT FOUND"<<endl;

插入

cpp 复制代码
//插入一个元素
set<int> s;
s.insert(10);
//插入多个元素
vector<int> array{1, 2, 3};
int a[] = {1,2,3};
set<int> s;
s.insert(array.begin(), array.end()); 
s.insert(a,a+3);
//使用emplace函数插入元素
set<int> s;
s.emplace(10);

删除

语法格式

cpp 复制代码
set_name.erase(element);//删除 set 容器中值为 val 的元素
name.erase(iterator position);//删除 position 迭代器指向的元素
name.erase(iterator start, iterator end);//删除 [start,end) 区间内的所有元素

示例

cpp 复制代码
set<int> myset={1,2,3,4,5};
myset.erase(30);
myset.erase(myset.find(3));
myset.erase(myset.begin(),myset.end())

Reference:

https://vimsky.com/examples/usage/unordered_set-erase-function-in-c-stl.html

https://www.cainiaojc.com/cpp/cpp-set-erase-function.html

https://c.biancheng.net/view/7198.html

https://blog.csdn.net/chenyijun/article/details/119065095

清空

cpp 复制代码
myset.clear();

遍历

迭代器遍历

cpp 复制代码
set<int> myset={1,2,3,4,5};

for(auto it = mySet.begin(); it != mySet.end(); it++)
{
    cout<<*it<<" ";
}
cout<<endl;

for循环新用法

cpp 复制代码
set<int> myset={1,2,3,4,5};
for(auto i : myset){
	cout<<i<<endl;
}

lower_bound()、upper_bound()

lower_bound(key_value) :返回第一个大于等于key_value的定位器

upper_bound(key_value):返回第一个大于key_value的定位器

cpp 复制代码
set<int> s={1,2,3,4,5};

cout<<*s.lower_bound(1)<<" ";
cout<<*s.lower_bound(2)<<" ";
cout<<*s.upper_bound(3)<<" ";

//输出:1 2 4

set与unordered_set的区别

set与unordered_set一样,都是关联式容器,和 map 容器不同,使用 set 容器存储的各个键值对,要求键 key 和值 value 必须相等。

当使用 set 容器存储键值对时,只需要为其提供各键值对中的 value 值(也就是 key 的值)即可。

使用 set 容器存储的各个元素的值必须各不相同

从语法上讲 set 容器并没有强制对存储元素的类型做 const 修饰,即 set 容器中存储的元素的值是可以修改的。但是,C++ 标准为了防止用户修改容器中元素的值,对所有可能会实现此操作的行为做了限制,使得在正常情况下,用户是无法做到修改 set 容器中元素的值的。

主要区别:

set

  • 定义于头文件
  • 底层实现通常是平衡二叉树
  • 元素自动排序,这为查找元素提供了良好性能,但同时也造成了一个重要限制:不能直接改变元素值,因为这会打乱原本正确的顺序
  • 查找函数具有对数复杂度
  • 要改变元素的值,必须先删除该元素,再插入新元素

unordered_set

  • 定义于<unordered_set>头文件
  • 底层实现通常是hash-table
  • 元素是无序的
  • 插入、删除、查找元素的时间复杂度是常量的(排除偶尔的rehashing导致的线性复杂度)

总结

综上,以下情况使用set:

  • 需要排序的数据
  • 需要通过前序、后序等方式遍历元素或者查找前继后继元素
  • 想要使用binary_search(), lower_bound() and upper_bound()等需要在有序元素上使用的方法
  • 其他平衡二叉树具有而hash表没有的优点

在以下情况使用unordered_set:

  • 仅需要保存互异的元素而不需要排序
  • 只需要获取单个元素而不需要遍历

两者的区别参考:

https://zhuanlan.zhihu.com/p/439197313

https://blog.csdn.net/bryant_zhang/article/details/111600209

https://zhuanlan.zhihu.com/p/131009604

reference:

https://blog.csdn.net/weixin_44668898/article/details/102089892

还可以参考:

https://zhuanlan.zhihu.com/p/682656691

相关推荐
小刘同学3215 分钟前
C++11 特性
c++·c11新特性
军训猫猫头5 分钟前
1.如何对多个控件进行高效的绑定 C#例子 WPF例子
开发语言·算法·c#·.net
success19 分钟前
【爆刷力扣-数组】二分查找 及 衍生题型
算法
真的想上岸啊19 分钟前
学习C++、QT---18(C++ 记事本项目的stylesheet)
开发语言·c++·学习
m0_5522008223 分钟前
《UE5_C++多人TPS完整教程》学习笔记40 ——《P41 装备(武器)姿势(Equipped Pose)》
c++·游戏·ue5
明天好,会的26 分钟前
跨平台ZeroMQ:在Rust中使用zmq库的完整指南
开发语言·后端·rust
Orlando cron1 小时前
数据结构入门:链表
数据结构·算法·链表
丁劲犇1 小时前
用 Turbo Vision 2 为 Qt 6 控制台应用创建 TUI 字符 MainFrame
开发语言·c++·qt·tui·字符界面·curse
旷世奇才李先生1 小时前
Next.js 安装使用教程
开发语言·javascript·ecmascript
牛客企业服务2 小时前
2025年AI面试推荐榜单,数字化招聘转型优选
人工智能·python·算法·面试·职场和发展·金融·求职招聘