set的基本用法

本文详细介绍了C++标准模板库中的set容器的基本用法,包括插入、删除、查找等操作,并展示了如何通过重载运算符来自定义排序规则。

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

set是一棵红黑树,在一些操作上十分高效,还具有许多priority_queue没有的功能

下面是基本用法

//set
#include<set>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

set<int> s;

int main()
{
    int n; 
    cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int t; 
        cin >> t;
        s.insert(t);
    }


//遍历:   
    set<int>::iterator it;    //正向迭代器 
    for(it = s.begin(); it != s.end(); it++)    //正向遍历(即由小到大输出) 
        cout << *it << " ";

    cout << endl;

    set<int>::reverse_iterator rit;    //反向迭代器 
    for(rit = s.rbegin(); rit != s.rend(); rit++)    //反向遍历(即由大到小输出) 
        cout << *rit << " ";

//元素的删除:可以删除迭代器上的元素,等于某键值的元素,区间上的元素和清空集合
    it = s.begin();
    for(int i = 1; i <= 2; i++)
        s.erase(it++);

    for(it = s.begin(); it != s.end(); it++)    
        cout << *it << " ";
    cout << endl;

    s.clear();
    for(it = s.begin(); it != s.end(); it++)    
        cout << *it << " ";
    cout << endl;

//元素的检索: 用s.find(),如果找到,则返回迭代器位置,否则返回s.end();
    s.insert(5);
    cout << *s.find(5) << endl;
    if(s.find(20) == s.end()) cout << "NO";


    return 0;
}

很多用到set时需要进行重载运算符,用法如下

//set
#include<set>
#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

struct mycmp        //当set中的元素不是结构体时 
{
    bool operator () (const int &a, const int &b)
    {
        return a%10 < b%10;
    }
};
set<int, mycmp> s1;

struct point
{
    int x, y;
    bool operator < (const point &a) const      //当set中的元素是结构体时,直接写在结构体中 
    {
        return x < a.x;     //按照x从小到大排序 
    }
};
set<point> s2;

int main()
{
    int n; cin >> n;
    for(int i = 1; i <= n; i++)
    {
        int t; cin >> t; s1.insert(t);
    }

    set<int, mycmp>::iterator it1;

    for(it1 = s1.begin(); it1 != s1.end(); it1++)
        cout << *it1 <<  " ";
    cout << endl;

    for(int i = 1; i <= n; i++)
    {
        point t;
        cin >> t.x >> t.y;
        s2.insert(t);
    }
    set<point>::iterator it2;
    for(it2 = s2.begin(); it2 != s2.end(); it2++)
        cout << (*it2).x << " ";


    return 0;
}
<think>好的,我现在需要回答用户关于C++中set数据结构的基本概念和使用方法的问题。首先,我要回顾一下自己对于set的了解。set是C++标准模板库(STL)中的一个关联容器,它存储的是唯一元素,并且元素会自动排序。通常内部是用红黑树实现的,所以插入、删除和查找的时间复杂度都是对数级别的。 接下来,我需要整理基本概念。用户可能想知道set的定义、特性以及如何声明和使用。根据引用[2],set需要包含头文件#include <set>,声明方式有几种,比如直接初始化、拷贝构造或者用迭代器范围初始化。特性方面,元素的唯一性和自动排序是关键点,可能还需要提到比较函数的自定义,比如结构体元素的情况,如引用[1]中提到的重载operator<来定义排序规则。 然后是关于基本用法的部分。用户可能需要知道如何插入元素、遍历、查找、删除以及获取大小等操作。插入用insert方法,遍历需要用到迭代器,比如set<int>::iterator。查找可以用find方法,删除用erase,还有size方法获取元素数量。这些在引用[2]里都有例子,比如s.insert(6)、s.find(3)等。 此外,自定义排序规则可能是一个重点,特别是当元素是结构体或者需要非默认排序时。引用[1]中的例子展示了在结构体内重载operator<,这样就可以根据特定字段排序。另外,可能提到C++11以后可以使用lambda表达式或者函数对象来自定义比较器,但要注意声明set时的模板参数。 还有需要注意的地方,比如set中的元素不能被修改,因为这会破坏排序。迭代器是const的,所以修改元素需要先删除再插入。另外,性能方面,由于基于红黑树,操作都是O(log n),但相比unordered_set(哈希表实现)在查找上可能稍慢,但保持了有序性。 在引用中提到的内容需要正确引用。例如,元素唯一性和自动排序来自引用[2],结构体比较来自引用[1],键值对的定义在引用[3]可能关联到map,但set是单一值。虚函数和多态性的引用[4]可能不直接相关,但需要避免混淆,因为set的实现不涉及虚函数,这部分可能不需要提及。 用户可能还会关心set的应用场景,比如需要有序且唯一元素的集合,或者需要快速查找、插入删除的情况。比如去重、维护有序数据等。 最后,生成相关问题时要围绕set的底层结构、性能、比较函数、与其他容器的区别等方面提问,帮助用户进一步学习。</think>### C++中set数据结构基本概念与使用方法 #### 一、基本概念 1. **定义** `set`是C++标准模板库(STL)中的**关联容器**,用于存储**唯一元素**(无重复值),且元素按**自动排序**规则排列[^2]。 底层通常通过**红黑树**(平衡二叉搜索树)实现,因此插入、删除和查找操作的时间复杂度均为$O(\log n)$[^3]。 2. **特性** - **元素唯一性**:不允许重复值,插入重复值时会被忽略[^2]。 - **自动排序**:默认按升序排列,支持自定义排序规则[^1]。 - **不可直接修改元素**:需先删除旧元素再插入新元素,以避免破坏内部有序性[^2]。 --- #### 二、基本用法 ##### 1. 声明与初始化 ```cpp #include <set> using namespace std; // 默认升序 set<int> s1; // 初始化列表 set<int> s2{1, 2, 3}; // 自定义排序规则(降序) set<int, greater<int>> s3; ``` ##### 2. 常用操作 | 操作 | 代码示例 | 说明 | |----------------|-----------------------------|-----------------------------| | 插入元素 | `s.insert(4);` | 插入值为4的元素[^2] | | 删除元素 | `s.erase(2);` | 删除值为2的元素 | | 查找元素 | `auto it = s.find(3);` | 返回指向3的迭代器,未找到则返回`s.end()` | | 遍历集合 | `for (auto x : s) {...}` | 范围遍历 | | 获取元素数量 | `int size = s.size();` | 返回集合中元素个数 | | 清空集合 | `s.clear();` | 移除所有元素 | ##### 3. 自定义排序规则(结构体示例) ```cpp struct Student { string name; int score; // 重载<运算符,按score降序排列 bool operator<(const Student& other) const { return score > other.score; } }; set<Student> s; // 此时集合按score从高到低排列 ``` --- #### 三、注意事项 1. **迭代器类型** `set`的迭代器是**双向迭代器**,支持`++`和`--`操作,但**不支持随机访问**(如`it + 3`)。 2. **性能优化** 若需更快的查找速度($O(1)$)且不要求有序性,可改用`unordered_set`(基于哈希表)。 3. **元素不可变性** 直接修改元素可能导致排序失效,必须通过删除旧值并插入新值实现修改: ```cpp auto it = s.find(oldValue); if (it != s.end()) { s.erase(it); s.insert(newValue); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值