set和multiset是STL里面的关联式容器,对其元素而言,实值和键值是统一的。元素会根据特定的排序准则自动排序,默认为升序排列。set和multiset中不能通过迭代器改变元素值,因为元素值即是键值,会破坏其组织。要改变元素值,必须先删除旧元素,再插入新元素。其底层实现均采用红黑树。set和multiset的不同点是set不允许元素值重复,而multiset允许出现重复元素。使用set和multiset之前须先含入头文件
namespace std {
template <class T,
class Compare = less<T>,
class Allocator = allocator<T> >
class set;
template <class T,
class Compare = less<T>,
class Allocator = allocator<T> >
class multiset;
}
第一个参数定义元素型别T;第二个参数定义排序准则,缺省使用less;可有可无的第三个参数用来定义内存模型,缺省的内存模型是allocator,由C++标准程序库提供。
1 .生成、复制和销毁
操作 | 效果 |
---|---|
set c | 产生一个空的set/multiset,不含任何元素 |
set c(op) | 产生一个以op为排序准则的空的set/multiset |
set c(beg, end) | 以区间[beg,end]内的元素产生一个set/multiset |
set c(beg, end, op) | 以区间[beg,end]内的元素产生一个以op为排序准则的set/multiset |
c.~set() | 销毁所有元素,释放内存 |
其中set可以下列形式:
set | 效果 |
---|---|
set |
一个以type数据为元素的set,排序准则为less<> |
set |
一个以type数据为元素的set,排序准则为op |
multiset |
一个以type数据为元素的multiset,排序准则为less<> |
multiset |
一个以type数据为元素的multiset,排序准则为op |
2 .非变动性操作
操作 | 效果 |
---|---|
c.size() | 返回容器的大小 |
c.empty() | 判断容器是否为空,等同于size()==0,但可能更快 |
c.max_size() | 返回可容纳的最大元素数量 |
c1 == c2 | 判断c1是否等于c2 |
c1 != c2 | 判断c1是否不等于c2 |
c1 == c2 | 判断c1是否等于c2 |
c1 < c2 | 判断c1是否小于c2 |
c1 > c2 | 判断c1是否大于c2 |
c1 <= c2 | 判断c1是否小于等于c2 |
c1 >= c2 | 判断c1是否大于等于c2 |
3 .特殊的搜寻函数
操作 | 效果 |
---|---|
count(elem) | 返回元素值为elem的元素个数 |
find(elem) | 返回值为elem的第一个元素的迭代器,找不到返回end() |
lower_bound(elem) | 返回elem第一个可安插位置,即第一个值>=elem的元素位置 |
upper_bound(elem) | 返回elem最后一个可安插位置,即第一个值>elem的元素位置 |
equal_range(elem) | 返回elem可安插的第一个和最后一个位置,即值==elem的元素区间 |
4 .赋值函数
这些操作函数中,赋值操作的两端容器必须具有相同型别。如果排序准则不同,准则本身也会被赋值或交换。
操作 | 效果 |
---|---|
c1 = c2 | 将c2中所有元素赋值给c1 |
c1.swap(c2) | 将c1和c2中的元素互换 |
swap(c1,c2) | 同上,此为全局函数 |
5 .迭代器相关函数
操作 | 效果 |
---|---|
c.begin() | 返回一个双向迭代器,指向第一元素 |
c.end() | 返回一个双向迭代器,指向最后元素的下一位置 |
c.rbegin() | 返回一个逆向迭代器,指向逆向遍历时第一个元素的位置 |
c.rend() | 返回一个逆向迭代器,指向逆向遍历时最后一个元素的下一位置 |
对迭代器操作而言,所有的元素都被视为常数,这可确保不会人为改变元素的值,从而打乱既定顺序。
6 .元素的安插、移除函数
安插移除多个元素时,单一调用比多次调用快得多。
操作 | 效果 |
---|---|
c.insert(elem) | 安插一份elem副本,若是set返回pair<新元素位置,是否成功(bool)>;若是multiset,返回新元素位置 |
c.insert(pos,elem) | 安插一份elem副本,pos提示搜寻起点,返回结果同上 |
c.insert(beg,end) | 将区间[beg,end]内所有元素副本安插到c,无返回值 |
c.erase(elem) | 移除所有与elem相等的元素,返回被移除元素的个数 |
c.erase(pos) | 移除迭代器pos所指位置上的元素,无返回值 |
c.erase(beg,end) | 移除区间[beg,end]内的所有元素,无返回值 |
c.clear() | 移除全部元素,将容器清空 |
//pair中的first成员返回新元素的位置,second成员返回安插是否成功
pair<iterator, bool> insert(const value_type& elem);
iterator insert(iterator pos_hint, const value_type& elem);
iterator insert(const value_type& elem);
iterator insert(iterator pos_hint, const value_type& elem);
如果multiset内含重复元素,不能使用erase()删除重复元素中的第一个,可以这么做:
std::multiset coll;
...
std::multiset ::iterator pos;
pos=coll.find(elem);
if(pos != coll.end()){
coll.erase(pos);
}
序列式容器提供下面的erase()成员函数:
iterator erase(iterator pos);
iterator erase(iterator beg, iterator end);
关联式容器提供下面的erase()成员函数:
void erase(iterator pos);
void erase(iterator beg, iterator end);
//example of set
#include
#include
#include
#include
using namespace std;
int main()
{
typedef set<int, greater<int> > IntSet;
IntSet coll1;
coll1.insert(4);
coll1.insert(3);
coll1.insert(5);
coll1.insert(1);
coll1.insert(6);
coll1.insert(2);
coll1.insert(5);
IntSet::iterator pos;
for (pos = coll1.begin(); pos != coll1.end(); ++pos){
cout << *pos << " ";
}
cout << endl;
pairbool> status = coll1.insert(-1);
if (status.second){
cout << "-1 inserted as element "
<< distance(coll1.begin(), status.first) + 1
<< endl;
}
else{
cout << "-1 always exists" << endl;
}
set<int> coll2(coll1.begin(), coll1.end());
copy(coll2.begin(), coll2.end(),
ostream_iterator<int>(cout, " "));
cout << endl;
coll2.erase(coll2.begin(), coll2.find(3));
int num;
num = coll2.erase(5);
cout << num << " elements removed" << endl;
copy(coll2.begin(), coll2.end(),
ostream_iterator<int>(cout, " "));
cout << endl;
}
//example of multiset
#include
#include
#include
#include
using namespace std;
int main()
{
typedef multiset<int, greater<int> > IntSet;
IntSet coll1;
coll1.insert(4);
coll1.insert(3);
coll1.insert(5);
coll1.insert(1);
coll1.insert(6);
coll1.insert(2);
coll1.insert(5);
IntSet::iterator pos;
for (pos = coll1.begin(); pos != coll1.end(); ++pos){
cout << *pos << " ";
}
cout << endl;
IntSet::iterator ipos = coll1.insert(4);
cout << "4 inserted as element "
<< distance(coll1.begin(), ipos) + 1
<< endl;
multiset<int> coll2(coll1.begin(), coll1.end());
copy(coll2.begin(), coll2.end(), ostream_iterator<int>(cout, " "));
cout << endl;
coll2.erase(coll2.begin(), coll2.find(3));
int num;
num = coll2.erase(5);
cout << num << " elements removed" << endl;
copy(coll2.begin(), coll2.end(), ostream_iterator<int>(cout, " "));
cout << endl;
}