STL集合

1.集合的概念

集合,简称集,是数学中一个基本概念,也是集合论的主要研究对象。集合论的基本理论创立于19世纪,关于集合的最简单的说法就是在朴素集合论(最原始的集合论)中的定义,即集合是“确定的一堆东西”,集合里的“东西”则称为元素。现代的集合一般被定义为:由一个或多个确定的元素所构成的整体。

生活中的关于集合的例子很多:

  1. 北京海淀区中学的 105 班的同学,这就是一个集合。这个集合里面会有一堆同学,而且是非常明确的,每个同学都不一样。

  2. 广东中考的科目,这也是一个集合,按照目前的规定,包含了:语文、数学、英语、物理、化学、政治、历史、体育。

  3. 佛山市南海区的公交车路线,这也是一个集合,里面包含很多条路线。

按照数学上的概念,集合是没有顺序的,例如,{ 张三、李四、王五 } 这个集合其实等同于 { 王五、张三、李四 } 。所以,集合本身不解决成员出现的先收顺序问题。

但是,在信息学里面,我们常常要做意见事情就是检查一下某个东西是否在一个集合里面。如果这个集合内的成员是没有顺序的话,那么我们就要枚举每一个集合元素,才能知道某个东西是不是在集合里面。所以,计算机的算法里面额外引入了一些功能,那就是对集合的元素进行排序,那么检查集合成员的时候就可以基于二分法去检查,计算福大度就从 O(N) 降低为 O(ln N)。但是,我们需要知道,这仅仅是因为工程实现上的需要引入的额外功能,这个功能和数学里面讲的集合没有必然性。

STL 模板就就包含了集合这个容器。这个容器把几乎所有的集合功能都实现好了,我们只需要按照一定的格式和方法去运用就可以了。使用 STL 模板可以简化我们的代码,提升代码的效率,增强代码的可读性。

2.STL 的 set 容器

2.1 set 的定义

//语法
//set <数据类型> 集合实例名字;

set <int> a; // 创建 int 类型的集合 a
set <long long> b; // 创建 long long 类型的集合 a
set <string> c; // 创建 a 类型的集合 a
struct student{
    int id;
    string name;
    operator < (student a){
        return id<a.id; 
    };// 结构体之间需要能比较,才能排序。set 是有序容器,如果不能比较,就不能创建结构体的集合
}
set <student> e; // 创建结构体 student 的集合 e

2.2 set 的函数

2.2.1 insert

往集合内插入一个元素。假设集合内已经存在这个元素了,就会什么都不做(不会报错)

set <int> s;
s.insert(3);
s.insert(4);
s.insert(1);
s.insert(4); // 执行这句不会报错,但是因为之前就已经有了 4 ,所以 4 就不会重复插入了

2.2.2 begin() 和 end()

begin() 返回集合的第一个元素的指针。end()返回最后一个元素后面的指针(注意,因为是左闭右开,所以这个 end() 返回的指针不是有效数据。

2.2.3 rbegin() 和 rend()

和 begin()/end() 类似,只不过是反向的。rend() 返回集合最后一个元素的指针(不是空的),rbegin() 返回第一元素之前的指针(注意,因为才有左开右闭原则,所以 rbegin() 其实是空指针)。

2.2.4 find

通过 find 函数可以查找集合内是否存在一个元素。find 函数返回的是一个指针。如果找不到,返回的是空指针(就是 end() 了)。

set <int> s;
for(int i=1;i<100;i++)
    s.insert(i);

set <int> :: iterator it; // 迭代器,其实是指针变量 

it = s.find(5); // 查找 5 ,返回对应的元素的指针

cout<< *it; // it 指向的是 5,通过 * 运算,获得它的值,所以输出的是 5

it = s.find(500); // 查找500,集合里找不到,所以会得到 end();

if(it==s.end()) cout<<"集合里没有 500,找不到";

2.2.5 lower_bound() 和 upper_bound()

lower_bound 是大于等于查找,lower_bound(a) 返回大于等于 a 的最小的那个元素。

lower_bound 是大于查找,upper_bound(a) 返回大于 a 的最小的那个元素。

set <int> s;
s.insert(7);
s.insert(11);
s.insert(13);
s.insert(15);
s.insert(20);

set <int> :: iterator it; // 迭代器,其实是指针变量 

it = s.lower_bound(13); // 找大于等于 13 的最小的那个数
cout<< *it <<endl; // 找到 13

it = s.upper_bound(13); // 找大于 13 的最小的那个数
cout<< *it <<endl; // 找到 15

it = s.upper_bound(25); // 找大于 25 的最小的那个数 ,找不到
// 所以 it 会等于 s.end()

2.2.6 clear()

清空整个集合(删除全部元素)

set <int> s;
s.insert(3);
s.insert(4);
s.insert(2);
s.clear(); // 集合清空

2.2.7 erase()

erase 是一个重载函数,输入的参数可以是一个值,也可以是一个指针(迭代器)。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	set <int> s;
	s.insert(7);
	s.insert(11);
	s.insert(13);
	s.insert(15);
	s.insert(20);
	
	set <int> :: iterator it; // 迭代器,其实是指针变量 
	
	s.erase(7);
	it = s.find(13);
	s.erase(it);
	
	set <int> :: reverse_iterator it2; // 反向迭代器
	for(it2=s.rbegin() ; it2!=s.rend(); it2++) // 从大到小输出 集合 元素
		printf("%d ",*it2); 

	return 0;
}

后面我会讲下数学上的集合。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值