set是关联容器。其键值就是实值,实值就是键值,不可以有重复,所以我们不能通过set的迭代器来改变set的元素的值,set拥有和list相同的特性:当对他进行插入和删除操作的时候,操作之前的迭代器依然有效。当然删除了的那个就没效了。set的底层结构是RB-tree,所以是有序的。
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>.
二:set里的基本操作
我们可以通过下面的方法来实例化一个set对象
std::set<int> s;那个s这个对象里面存贮的元素是从小到大排序的,(因为用std::less作为比较工具。)
如果要想在s里面插入数据,可以用inset函数(set没用重载[]操作,因为set本生的值和索引是相同的)
s.insert(3);s.insert(5).....
因为set是集合,那么集合本身就要求是唯一性,所以如果要像set里面插入数据和以前的数据有重合,那么插入不成功。
可以通过下面的方法来遍历set里面的元素
1 2 3 4 5 | std::set< int >::iterator it = s.begin(); while (it!=s.end()) { cout<<*it++<<endl; //迭代器依次后移,直到末尾。 } |
如果要查找一个元素用find函数,it = s.find(3);这样it是指向3的那个元素的。可以通过rbegin,rend来逆向遍历
1 2 3 4 5 | std::set< int >::reverse_iterator it = s.rbegin(); while (it!=s.rend()) { cout<<*it++<<endl; } |
还有其他的一些操作在这就不一一列出了。
三:set向量的使用实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | #include <iostream> #include <string> #include <set> #include <algorithm> #include <iterator> using namespace std; /* 联合容器将值与关键字联合在一起,使用关键字来查找值, * 提供元素的快速访问,插入元素不能指定位置,容器自动处理插入位置 * STL 提供四种联合容器:set、multiset、map、multimap * set、multiset 存储一种元素,前者关键字不可重复,后者关键字可以重复。 * map、multimap 存储一对元素键与值,前者关键字不可重复,后者关键字可以重复。 */ int main() { const int N = 3; string s1[N] = { "xp" , "python" , "linux" }; string s2[N] = { "python" , "php" , "perl" }; set<string> sa(s1, s1 + N); // 声明一个集合sa,元素为数组s1 set<string> sb(s2, s2 + N); // 声明一个集合sb,元素为数组s2 set<string> sc; // 声明一个空集合sc ostream_iterator<string, char > out (cout, " " ); copy(sa.begin(), sa.end(), out); cout << "->set sa" << endl; copy(sb.begin(), sb.end(), out); cout << "->set sb" << endl; set_union(sa.begin(), sa.end(), sb.begin(), sb.end(), out); cout << "->set_union() 并集" << endl; set_intersection(sa.begin(), sa.end(), sb.begin(), sb.end(), out); cout << "->set_intersection() 交集" << endl; set_difference(sa.begin(), sa.end(), sb.begin(), sb.end(), out); cout << "->set_difference() 集合的差" << endl; set_difference(sb.begin(), sb.end(), sa.begin(), sa.end(), out); cout << "->set_difference() 集合的差" << endl; set_union(sa.begin(), sa.end(), sb.begin(), sb.end(), insert_iterator<set<string> >(sc, sc.begin() )); sc.insert( "delphi" ); copy(sc.begin(), sc.end(), out); cout << "->set sc" << endl; copy(sc.lower_bound( "perl" ), sc.upper_bound( "python" ), out); cout << "->显示集合区间" << endl; return 0; } |
作者:ACShiryu
出处:http://www.cnblogs.com/ACShiryu/
若非注明,本博客文章均为原创,版权归作者和博客园共有,欢迎转载,但必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
该文章也同步发布在我的新浪微博中-ACShiryu's weibo,欢迎收听。