您的位置:首页 > 其它

标准模板库(STL)学习指南之set集合

2014-11-29 13:22 239 查看



/* 联合容器将值与关键字联合在一起,使用关键字来查找值,

* 提供元素的快速访问,插入元素不能指定位置,容器自动处理插入位置

* STL 提供四种联合容器:set、multiset、map、multimap

* set、multiset 存储一种元素,前者关键字不可重复,后者关键字可以重复。

* map、multimap 存储一对元素键与值,前者关键字不可重复,后者关键字可以重复。

*/

set 是关联容器。其键值就是实值,实值就是键值,不可以有重复(如果需求要求是可重复的,则请使用multiset),所以我们不能通过set的迭代器来改变set的元素的值,set拥有和list相同的特性:当 对他进行插入和删除操作的时候,操作之前的迭代器依然有效。当然删除了的那个就没效了。set的底层结构是RB-tree,所以是有序的。平衡二叉检索树的检索使用中序遍历算法,检索效率高于vector、deque、和list的容器。另外,采用中序遍历算法可将键值由小到大遍历出来,所以,可以理解为平衡二叉检索树在插入元素时,就会自动将元素按键值从小到大的顺序排列。

Set的特性:

1.stl中特别提供了一种针对set的操作的算法:交集set_intersection,并集set_union,差集set_difference,对称差集set_symeetric_difference。

set模板类的声明:

template <

class key

class =Traitsless<key>

class Allocator=allocator<key>

>

class set。

其中个参数的意义如下:

key:要放入set里的数据类型,可以是任何类型的数据。

Traits:这是一个仿函数(关于仿函数是什么,我后面的文章会讲到)。提供 了具有比较功能的仿函数,来觉得元素在set里的排列的顺序,这是一个可选的参数,默认的是std::less<key>,如果要自己提供这 个参数,那么必须要遵循此规则:具有两个参数,返回类型为bool。

Allocator:空间配置器,这个参数是可选的,默认的是std::allocator<key>.

















遍历迭代器:

普通迭代器:

std::set<int>::iterator it = s.begin();

while(it!=s.end())

{

cout<<*it++<<endl;//迭代器依次后移,直到末尾。

}

反向迭代器:

std::set<int>::reverse_iterator it = s.rbegin();

while(it!=s.rend())

{

  cout<<*it++<<endl;

}

插入迭代器:

插入迭代器(Insert Iterator),又叫插入器(Inserter),是继上次的反向迭代器之后C++中的又一个迭代器适配器。插入迭代器的主要功能为把一个赋值操作转 换为把相应的值插入容器的操作。插入迭代器对标准算法库而言尤其重要。算法库对所有在容器上的操作有个承诺:决不修改容器的大小(不插入、不删除)。有了 插入迭代器,既使得算法库可以通过迭代器对容器插入新的元素,又不违反这一承诺,即保持了设计上的一致性。

插入迭代器提供了以下几种操作:*itr,itr++,++itr,itr = value。但实际上,前三种操作为“空操作”(no-op),仅仅返回itr。第四种操作itr = value才是插入迭代器的核心,这个操作通过调用容器的成员函数(push_back(),push_front(),insert(),取决于插入器 类型)把value插入到插入器对应容器的相应的位置上。

插入迭代器分为三种类型:尾部插入器(back_insert_iterator),首部插入器(front_insert_iterator)和普通插 入器(insert_iterator)。第一种通过调用容器的push_back成员函数来插入元素,因此这种插入器只对 vector,list,deque和string有效。 第二种通过调用容器的push_front成员函数来插入元素,因此它只对list和deque有效。第三种通过调用insert成员函数来插入元素,并 由用户指定插入位置,它对所有标准的容器类型都有效,因为所有容器都定义了insert成员函数。

ostream_iterator

ostream_iterator属于I/O流STL适配器





自定义比较函数

使用insert将元素插入到集合中去的时候,集合会根据设定的比较函数奖该元素放到该放的节点上去。在定义集合的时候,如果没有指定比较函数,那么采用默认的比较函数,即按键值从小到大的顺序插入元素。但在很多情况下,需要自己编写比较函数。

编写比较函数有两种方法。

(1)如果元素不是结构体,那么可以编写比较函数。下面的程序比较规则为按键值从大到小的顺序插入到集合中。

#include "stdafx.h"

#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 a > b;

}

};

int main()

{

set<int, mycomp> s; //采用比较函数mycomp

s.insert(5); //第一次插入,可以插入

s.insert(1);

s.insert(6);

s.insert(3);

s.insert(5); //第二次插入,重复元素,不会插入

set<int,mycomp>::iterator it;

for(it = s.begin(); it != s.end(); it++)

cout <<*it<<" ";

cout << endl;

return 0;

}









(2)如果元素是结构体,那么可以直接把比较函数写在结构体内。



#include "stdafx.h"

#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 a > b;

}

};

int main()

{

set<int, mycomp> s; //采用比较函数mycomp

s.insert(5); //第一次插入,可以插入

s.insert(1);

s.insert(6);

s.insert(3);

s.insert(5); //第二次插入,重复元素,不会插入

set<int,mycomp>::iterator it;

for(it = s.begin(); it != s.end(); it++)

cout <<*it<<" ";

cout << endl;

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: