STL set

 今日做SRM,用到了SET,整理一下
   Set is a Sorted Associative Container that stores objects of type Key. Set is a Simple Associative Container, meaning that its value type, as well as its

key type, is Key. It is also a Unique Associative Container, meaning that no two elements are the same.
   Set and multiset are particularly well suited to the set algorithms includes, set_union, set_intersection, set_difference, and set_symmetric_difference.

The reason for this is twofold. First, the set algorithms require their arguments to be sorted ranges, and, since set and multiset are Sorted Associative

Containers, their elements are always sorted in ascending order. Second, the output range of these algorithms is always sorted, and inserting a sorted

range into a set or multiset is a fast operation: the Unique Sorted Associative Container and Multiple Sorted Associative Container requirements

guarantee that inserting a range takes only linear time if the range is already sorted.

   Set has the important property that inserting a new element into a set does not invalidate iterators that point to existing elements. Erasing an element

from a set also does not invalidate any iterators, except, of course, for iterators that actually point to the element that is being erased.

  set和map都是用平衡二叉树写的模板(sorted associative contaniers),所以元素升序排列(sorted in ascending order),输出有序。Set具有一个很重

要的性质,插入元素不会使指向已有元素的迭代器失效。

在SGI上有关于set的代码:
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;

struct ltstr
{
 bool operator()(const char* s1, const char* s2) const
 {
  return strcmp(s1, s2) < 0;
 }
};

int main()
{
 const int N = 6;
 const char* a[N] = {"isomer", "ephemeral", "prosaic",
  "nugatory", "artichoke", "serif"};
 const char* b[N] = {"flat", "this", "artichoke",
  "frigate", "prosaic", "isomer"};

 set<const char*, ltstr> A(a, a + N);
 set<const char*, ltstr> B(b, b + N);
 set<const char*, ltstr> C;

 cout << "Set A: ";
 copy(A.begin(), A.end(), ostream_iterator<const char*>(cout, " "));
 cout << endl;
 cout << "Set B: ";
 copy(B.begin(), B.end(), ostream_iterator<const char*>(cout, " "));  
 cout << endl;

 cout << "Union: ";
 set_union(A.begin(), A.end(), B.begin(), B.end(),
  ostream_iterator<const char*>(cout, " "),
  ltstr());  
 cout << endl;

 cout << "Intersection: ";
 set_intersection(A.begin(), A.end(), B.begin(), B.end(),
  ostream_iterator<const char*>(cout, " "),
  ltstr());   
 cout << endl;

 set_difference(A.begin(), A.end(), B.begin(), B.end(),
  inserter(C, C.begin()),
  ltstr());
 cout << "Set C (difference of A and B): ";
 copy(C.begin(), C.end(), ostream_iterator<const char*>(cout, " "));
 cout << endl;
}


网上有一篇不错的关于STL set的文章:
http://blog.csdn.net/wangji163163/archive/2009/01/09/3740948.aspx

set是关联容器。其键值就是实值,实值就是键值,不可以有重复,所以我们不能通过set的迭代器来改变set的元素的值,set拥有和list相同的特

性:当对他进行插入和删除操作的时候,操作之前的迭代器依然有效。当然删除了的那个就没效了。set的底层结构是RB-tree,所以是有序的。

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

些算法稍后会讲到。

一:set模板类的声明。

template <
   class Key,
   class Traits=less<Key>,
   class Allocator=allocator<Key>
>
class set。

其中个参数的意义如下:

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

Traits:这是一个仿函数(关于仿函数是什么,我后面的文章会讲到)。提供了具有比较功能的仿函数,来觉得元素在set里的排列的顺序,这是

一个可选的参数,默认的是std::less<key>,如果要自己提供这个参数,那么必须要遵循此规则:具有两个参数,返回类型为bool。

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

二:set里的基本操作

我们可以通过下面的方法来实例化一个set对象

std::set<int> s;那个s这个对象里面存贮的元素是从小到大排序的,(因为用std::less作为比较工具。)

如果要想在s里面插入数据,可以用inset函数(set没用重载[]操作,因为set本生的值和索引是相同的)

s.insert(3);s.insert(5).....

因为set是集合,那么集合本身就要求是唯一性,所以如果要像set里面插入数据和以前的数据有重合,那么插入不成功。

可以通过下面的方法来遍历set里面的元素

std::set<int>::iterator it = s.begin();
while(it!=s.end())
{
   cout<<*it++<<endl;//迭代器依次后移,直到末尾。
}

如果要查找一个元素用find函数,it = s.find(3);这样it是指向3的那个元素的。可以通过rbegin,rend来逆向遍历

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

while(it!=s.rend())

{cout<<*it++<<endl;}

还有其他的一些操作在这就不一一列出了。

三:与set相关的一组算法

set_intersection() :这个函数是求两个集合的交集。下面是stl里的源代码

template<class _InIt1,
class _InIt2,
class _OutIt> inline
_OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1,
   _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
{ // AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
for (; _First1 != _Last1 && _First2 != _Last2; )
   if (*_First1 < *_First2)
    ++_First1;
   else if (*_First2 < *_First1)
    ++_First2;
   else
    *_Dest++ = *_First1++, ++_First2;
return (_Dest);
}

这是个模板函数,从上面的算法可以看出,传进去的两个容器必须是有序的。_Dest指向输出的容器,这个容器必须是预先分配好空间的,否则

会出错的,返回值指向保存结果的容器的尾端的下一个位置。eg.

set_union() :求两个集合的并集,参数要求同上。

std::set_difference():差集

set_symmetric_difference():得到的结果是第一个迭代器相对于第二个的差集并上第二个相当于第一个的差集。代码:

struct compare
{
bool operator ()(string s1,string s2)
{
   return s1>s2;
}///自定义一个仿函数
};
int main()
{
typedef std::set<string,compare> _SET;
_SET s;
s.insert(string("sfdsfd"));
s.insert(string("apple"));
s.insert(string("english"));
s.insert(string("dstd"));
cout<<"s1:"<<endl;
std::set<string,compare>::iterator it = s.begin();
while(it!=s.end())
   cout<<*it++<<"   ";
cout<<endl<<"s2:"<<endl;
_SET s2;
s2.insert(string("abc"));
s2.insert(string("apple"));
s2.insert(string("english"));
it = s2.begin();
while(it!=s2.end())
   cout<<*it++<<"   ";
cout<<endl<<endl;

string str[10];
string *end = set_intersection(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//求交集,返回值指向str最后一个元素的尾端
cout<<"result of set_intersection s1,s2:"<<endl;
   string *first = str;
   while(first<end)
    cout <<*first++<<" ";
   cout<<endl<<endl<<"result of set_union of s1,s2"<<endl;
   end = std::set_union(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//并集
   first = str;
   while(first<end)
    cout <<*first++<<" ";
   cout<<endl<<endl<<"result of set_difference of s2 relative to s1"<<endl;
   first = str;
   end = std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//s2相对于s1的差集
   while(first<end)
    cout <<*first++<<" ";
   cout<<endl<<endl<<"result of set_difference of s1 relative to s2"<<endl;
   first = str;
   end = std::set_difference(s2.begin(),s2.end(),s.begin(),s.end(),str,compare());//s1相对于s2的差集

   while(first<end)
    cout <<*first++<<" ";
   cout<<endl<<endl;
   first = str;
end = std::set_symmetric_difference(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//上面两个差集的并集
   while(first<end)
    cout <<*first++<<" ";
   cout<<endl;
}

set<int>   s3   ;  
set<int>::iterator   iter   =   s3.begin()   ;  
set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,iter));  
copy(s3.begin(),s3.end(),   ostream_iterator<int>(cout,"   "));


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wangji163163/archive/2009/01/09/3740948.aspx

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值