C++ set 常用部分

关键特性

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

定义及初始化

#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的初始值

一些基本操作

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)方法寻找带有特定键的元素,返回的是迭代器。

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时表示元素在集合中,反之不在。

set<int> s = {1,2,3,4,5};

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

插入

//插入一个元素
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);

删除

语法格式

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

示例

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

清空

myset.clear();

遍历

迭代器遍历

set<int> myset={1,2,3,4,5};

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

for循环新用法

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的定位器

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

相关推荐

  1. git 部分方法

    2024-03-30 16:38:03       24 阅读
  2. C++ set 部分

    2024-03-30 16:38:03       21 阅读
  3. C++ map 部分

    2024-03-30 16:38:03       16 阅读
  4. eclipse部分快捷键的使用

    2024-03-30 16:38:03       36 阅读

最近更新

  1. opencv 设置超时时间

    2024-03-30 16:38:03       0 阅读
  2. Nginx Websocket 协议配置支持

    2024-03-30 16:38:03       0 阅读
  3. Perl语言入门到高级学习

    2024-03-30 16:38:03       0 阅读
  4. 【 HTML基础知识】

    2024-03-30 16:38:03       0 阅读
  5. Vue3框架搭建3:配置说明-prettier配置

    2024-03-30 16:38:03       1 阅读

热门阅读

  1. 机器学习 - 创建一个PyTorch classification model

    2024-03-30 16:38:03       23 阅读
  2. P1068 [NOIP2009 普及组] 分数线划定 Python

    2024-03-30 16:38:03       23 阅读
  3. 简述如何系统地学习Python

    2024-03-30 16:38:03       21 阅读
  4. SpringBoot -- 整合SpringMVC

    2024-03-30 16:38:03       23 阅读
  5. 用静态工厂方法代替构造器

    2024-03-30 16:38:03       21 阅读