set联合容器范例
set是多个概念的模型,它是一个联合集合,可反转,可排序,关键字是唯一的,所以它只能存储同一种类型的值。
set也使用模板参数来提供要存储的值的类型:
set<string> A; // a set of string objects
可选的第二个模板参数可以用于指示用来对关键字进行排序的比较函数或对象。默认情况下,将使用less<>模板。
set<string, less<string> > A; // older implementation
set有一个将迭代器的区间作为参数的构造函数,这样提供了一种将集合初始化为数组内容的简单方法:
const int N = 6;
string s1[N] = {"buffoon","thinkers","for","heavy","can","for"};
set<string> A(s1, s1 + N); // initialize set A using a range form array
ostream_iterator<string,char> out (cout, " ");
copy(A.begin(), A.end(), out);
由于set中关键字是唯一的,而上面字符串中"for"在数组中出现了2次,所以会被压缩为一个元素。压缩后的集合还将被排序,输出如下:
buffoon can for heavy thinkers
数学为集合定义了一些标准操作,例如,并集包含两个集合合并后的内容。如果两个集合中包含相同的值,则这个值将在并集中只出现一次,这是因为关键字是唯一的。交集包含两个集合公有的元素。两个集合的差是第一个集合减去两个集合公有的元素。
STL提供了支持这些操作的算法。它们是通用函数,而不是方法,因此它们不是只能够用于set对象。不过,所有的set对象都自动满足使用这些算法的先决条件,即容器是经过排序的。
set_union()函数接受5个迭代器参数。前两个迭代器定义了一个集合的区间,接下来的两个定义了第二个集合的区间,最后一个迭代器是输出迭代器,指出将结果集合复制到什么位置。
例如,显示集合A和B的并集:
set_union(A.begin(), A.end(), B.begin(), B.end(),
ostream_iterator<string,char> out (cout, " ") );
假设要将结果放到集合C中,则最后一个参数应是一个指向C的迭代器。但不能用C.begin(),原因有二。
首先,联合集合将关键字看做是常量,所有C.begin()返回的迭代器是一个固定迭代器,不能用作输出迭代器。
原因二是,与copy()相似,set_union()将覆盖容器中已有的数据,并要求容器有足够的空间来容纳新信息。C是空的,不能满足这种要求。
insert_iterator模板可以解决这两个问题。它可以将复制转换为插入。另外,它还模拟了输出迭代器概念。
因此,可以创建一个匿名insert_iterator,将信息复制给C :
set_union(A.begin(), A.end(), B.begin(), B.end(),
insert_iterator<ser<string> > (C, C.begin()) );
set_intersection()和set_difference()函数查找交集和获得两个集合的差,它们的接口与set_union()相同。
lower_bound()方法将关键字作为参数并返回一个迭代器,该迭代器指向集合中第一个不小于关键字参数的成员。
upper_bound()方法将关键字作为参数并返回一个迭代器,该迭代器指向集合中第一个大于关键字参数的成员。
例如,如果有一个字符串集合,则可以用这些方法来获得一个区间,该区间包含集合中"b"到"f"的所有字符串。
因为排序决定了插入的位置,所以这种类包含只指定要插入的信息,而不指定位置的插入方法。如果A和B是字符串集合,则可以这样做:
string s("tennis");
A.insert(s); //insert a value
B.insert(A.begin(), A.end() ); //insert a range