STL之set

1.set介绍
set容器是一种实现了平衡二叉树的数据结构,容器中的数据不能重复,即每个数据都是唯一的,并且会对存进去的数据进行自动排序。
构造set集合的主要目的是为了快速检索,去重与排序,使用set前,需要在程序头文件中包含声明#include< set>

2.set常用函数

insert():	插入元素
erase():	删除元素
find():		返回一个指向被查找元素的迭代器
begin():	返回指向第一个元素的迭代器
end():		返回指向最后一个元素下一个位置的迭代器
clear():	清除所有元素
size():		集合中元素的数目
swap():		交换两个集合变量
empty():	如果集合为空,返回true
rbegin():	返回指向集合中最后一个元素的反向迭代器
rend():		返回指向集合中第一个元素的反向迭代器
count():	返回某个值元素的个数

3.set容器的基本操作
a.创建set对象:
a.set<类型>对象名,如:set<int>a;
b.set<类型,比较结构体>对象名,如set<int,myComp>a;

set<const set&);//通过set的拷贝构造函数创建对象
如:set< int>a1;set< int>a2(a1);

c.set(first, last);//用迭代器区间(first, last)所指的元素,创建一个set对象

如:int a[] = {1,2,3,4,5};set< int>s(a,a + 5);

b.添加元素:
insert(key_value);将某一键值插入set中,返回值是pair< set< int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若该键值已经在set中,则iterator表示已存在的该键值在set中的位置。

如:
set< int>a;
a.insert(1);
a.insert(2);
a.insert(2);//重复的元素不会被插入
insert(first, last);
如:
int a[] = {1,2,3};set< int>s;
s.insert(a,a + 3);

c.删除元素:

erase(key_value),删除键值key_value的值
如:a.erase(1);
erase(iterator),删除迭代器iterato指向的值
如:a.erase(a.begin());//删除a中的第一个元素
erase(first, second);//删除迭代器(first,second)之间的值
如:a.erase(a.begin(),a.end());//删除全部元素
a.clear();//清除a中的所有元素

⚠️set中的erase()操作时不进行任何的错误检查的,比如定位器的是否合法等等,所以用的时候自己需要注意。

d.遍历访问:

//顺序遍历:
set<int> a;
set<int>::iterator it = a.begin();
for(;it != a.end();it++)
cout << *it << endl;
//反序遍历:
set<int>a;
set<int>::reverse_iterator rit = a.rbegin();
for(;rit != a.rend();rit++)
cout << *rit << endl;

⚠️关联容器的迭代器不支持it + n操作,仅支持it++操作。

e.查找元素:
find(key_value);//如果找到查找的键值,则返回该键值的迭代器位置,否则返回集合最后一个元素后一个位置的迭代器,即end();
如:

int b[] = {1,2,3,4,5};
set<int>a(bob + 5);
set<int>::iterator it;
it = a.find(3);
if(it != a.end()) cout << *it << endl;
else cout << "该元素不存在" << endl;
it = a.find(10);
if(it != a.end()) cout << *it << endl;
else cout << "该元素不存在" << endl;


输入结果:
3
该元素不存在

f.自定义比较函数:
set容器在判定已有元素a和新插入元素b是否相等时,是这么做的
(1)将a作为左操作数,b作为右操作数,再调用一次比较函数,并返回比较值;
(2)将b作为左操作数,a作为右操作数,再调用一次比较函数,并返回比较值;
也就是说,假如有比较函数f(x,y),要对已有元素a和新插入元素b进行比较时,会先进行f(a,b)操作,再进行f(b,a)操作,然后返回两个bool值
如果1,2两步的返回值都是false,则认为a、b时相等的,则b不会被插入set容器中;
如果1返回true而2返回false,那么认为b要排在a的后面,反之则b要排在a的前面;
如果1,2,两步的返回值都是true,则可能发生未知行为。

g.自定义比较结构体:
首先,定义比较结构体

struct myComp
{
	bool operator() (const 类型 &a,const 类型 &b)//重载"()"操作符
	{
		``````
		return ``````;	
	}
};
//然后,定义set
set<类型,myComp>s;

例子如下:自定义从大到小排序

#include<iostream>
#include<set>
using namespace std;

struct myComp
{
    bool operator()(const int &a,const int &b)
    {
        if(a != b)
            return a > b;
        else return false;//a与b相等时不插入
    }
};
int main()
{
    set<int,myComp> s;
    s.insert(1);
    s.insert(5);
    s.insert(4);
    s.insert(2);
    s.insert(1);//重复元素不插入
    set<int,myComp>::iterator it = s.begin();
    for(;it != s.end();it++)
        cout << *it << " ";
    cout << endl;
}
//输出结果:
5 4 2 1

h.重载"<"操作符:

首先,在结构体中,重载“<”操作符,自定义排序规则

struct 结构体
{
	bool operator < (const 结构体类型&a)
	{
		``````
		return (```);
	}
};
//然后定义set
//set<类型> s;

例题如下:

/*
 对含有姓名,编号,成绩的结构体,根据学号从小到大排序,同时根据编号去重
 */
#include<iostream>
#include<set>
using namespace std;

struct Student
{
    string name;
    int num;
    double grade;
    
    bool operator<(const Student &a) const
    {
        //按照编号从小到大排序,如果需要从大到小则用“<"
        if(a.num == num)//根据编号num去重
            return false;
        else return a.num > num;//a与b相等时不插入
    }
};
int main()
{
    set<Student> a;
    set<Student>::iterator it;
    Student stu;
    stu.name = "John";stu.num = 3256;stu.grade = 85.5;
    a.insert(stu);
    stu.name = "Tom";stu.num = 1749;stu.grade = 90.1;
    a.insert(stu);
    stu.name = "Bob";stu.num = 3256;stu.grade = 60.4;
    a.insert(stu);
    for(it = a.begin();it != a.end();it++)
        cout << (*it).num << " " << (*it).name << " " << (*it).grade << endl;
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Αиcíеиτеǎг

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

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

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

打赏作者

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

抵扣说明:

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

余额充值