利用C++STL容器的set集合去重排序并找出第K小的数

本文介绍了一种使用C++实现的算法,该算法通过读取一系列整数并将其插入到一个集合中来找到第K小的元素。集合会自动保持元素的排序,从而简化了查找过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实现代码:

#include<bits/stdc++.h>

using namespace std;


int main()
{
	int n,k,i,num,x,cnt;
	cin>>n>>k;
	set<int>S;
	for(i=1;i<=n;i++)
	{
		cin>>num;
		S.insert(num);
	}
	cnt=0;
	for(auto &x:S)
	{
		cnt++;
		if(cnt==k)
		{
			cout<<x<<endl;
		}
	}
	return 0;
}

 

<think>好的,用户想了解C++set集合的用法和特性。首先,我需要回忆一下set的基本概念。setSTL中的关联容器,存储唯一元素,且按特定排序规则自动排序。通常用红黑树实现,所以插入、删除、查找的时间复杂度都是O(log n)。这些是基本特性,应该先介绍。 接下来,用户需要具体的使用方法。比如如何定义和初始化set。根据引用[3],set的定义有几种方式:默认构造函、初始化列表、拷贝构造等。需要举例说明,比如std::set<int> s1;或者用已有容器的一部分初始化。 然后是常用操作,插入元素。引用[2]提到insert和emplace方法,还有emplace_hint。要说明insert返回pair,包含迭代器和是否插入成功的bool。emplace可以直接构造元素,避免临时对象,提高效率。emplace_hint则给出提示位置,可能优化插入速度,但需要正确使用。 关于元素的访问和查找,find方法返回迭代器,如果找不到则返回end()。count可以用来检查元素是否存在,因为set中元素唯一,所以count只能是0或1。这些方法在引用[3]中应该提到。 还有集合操作,比如集、交集、差集、对称差集。引用[1]中的set_difference,但用户需要知道这些算法在<algorithm>头文件中,需要结合inserter使用。例如求差集时,用std::set_difference,插入到结果容器中。要提到这些函的使用方法,以及参顺序的重要性,比如交换a和b的位置会影响结果。 另外,set的特性包括自动排序和元素唯一性。如果用户插入重复元素,insert会失败,emplace也是。这点需要强调,可能用户在处理重时会用到。 迭代器方面,set支持双向迭代器,可以正向和反向遍历。引用[3]中的例子展示了正向迭代器的使用,应该说明遍历的方法,比如用begin()和end()循环。 性能方面,要提到红黑树的结构保证了操作的复杂度,适用于需要频繁查找和有序输出的场景。比如维护一个有序不重复的集合,或者需要快速判断元素是否存在。 可能用户在实际使用中会遇到的问题,比如自定义排序规则。set默认是升序,但可以通过模板参改为降序或者自定义比较函。例如std::set<int, std::greater<int>>。这点在引用[3]中也有提到,需要说明如何修改排序方式。 总结的时候,要分点列出set的特性,如自动排序、唯一元素、高效操作,以及常用方法如插入、删除、查找,集合运算等。确保覆盖用户可能关心的各个方面,结合引用中的例子具体说明,比如emplace_hint的使用场景和注意事项。 最后,生成相关问题时要围绕set的扩展应用、性能优化、与其他容器的比较,以及高级操作如自定义排序等方面提问,帮助用户深入理解。</think>### C++ set 集合的使用方法与特性 #### 1. 基本特性 - **唯一元素**:set 容器中的元素具有唯一性,重复插入会被自动忽略[^3]。 - **自动排序**:元素按**严格弱序**规则(默认升序)自动排列,底层通过红黑树实现。 - **高效操作**:插入、删除、查找的时间复杂度均为 $O(\log n)$[^3]。 #### 2. 定义与初始化 ```cpp // 默认构造函(升序) std::set<int> s1; // 初始化列表 std::set<std::string> names = {"James", "Tom"}; // 自定义排序规则(降序) std::set<int, std::greater<int>> s2; ``` #### 3. 常用操作 - **插入元素**: ```cpp auto result = names.insert("Rose"); // 返回pair<iterator, bool> names.emplace("Lucy"); // 直接构造元素,避免临时对象[^2] ``` - **删除元素**: ```cpp names.erase("Tom"); // 通过值删除 names.erase(names.begin()); // 通过迭代器删除 ``` - **查找元素**: ```cpp auto it = names.find("Rose"); // 返回迭代器,未找到则返回end() bool exists = names.count("Tom"); // 返回0或1[^3] ``` #### 4. 集合运算 通过 `<algorithm>` 实现集合操作: ```cpp std::set<int> a{1,2,3}, b{2,3,4}, result; // 差集(a - b) std::set_difference(a.begin(), a.end(), b.begin(), b.end(), std::inserter(result, result.end())); // 结果为{1}[^1] // 对称差集(a ∪ b - a ∩ b) std::set_symmetric_difference(...); ``` #### 5. 性能优化技巧 - **emplace_hint**:若已知插入位置的大致范围,可提升效率: ```cpp auto it = names.emplace_hint(names.begin(), "PreInsert"); // 提示插入位置[^2] ``` - **迭代器失效**:删除操作仅影响被删元素的迭代器,其他迭代器仍有效。 #### 6. 典型应用场景 1. 维护**有序不重复据集**(如排行榜) 2. 快速**存在性判断**(比vector快100倍以上) 3. 重处理 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林下的码路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值