set
标准的STL关联式容器分为set(集合)和map(映射表)两大类。以及这两大类的衍生体multiset(多建集合)和multimap(多键映射表)。这些容器的底层机制均是以RB-tree(红黑树)完成的。RB-tree也是一个独立容器,但并不对外开放使用。
set 的特性是,所有元素都会根据元素的键值自动被排序,set的元素不像map那样可以同时拥有实值(value)和键值(key),set元素的键值就是实值,实值就是键值,set不允许两个元素有相同的键值。
我们可以通过set的迭代器改变set的元素值吗?不行,因为set的元素值就是其键值,关系到set元素的排列规则。如果任意改变set的元素值,会严重破坏set组织。set<T>::iterator 被定义为底层RB-tree的const_iterator,杜绝写入操作,换句话说,set iterators 是一种constant iterator(相对于 mutable iterator)。
set拥有和list相同的某些性质,当客户端对它进行元素新增操作(insert)或删除操作(erase)时,操作之前的所有迭代器,在操作完成之后都依然有效。当然,被删除的那个元素的迭代器必然是个例外。
由于RB-tree是一种平衡二叉搜索树,自动排序的效果很是不错,所以标准的STL set 即以RB-tree为底层机制。又由于map所开放的各种操作接口,RB-tree也都提供了,所以几乎所有的set的操作行为,都只是转调用RB-tree的操作行为而已。
multiset 的特性以及用法与set完全相同,唯一的差别在于它允许键值重复,因此它的插入操作采用的是底层机制RB-tree的insert_equal()而非insert_unique()。
set::set()函数 功能:构造set
#include<iostream>
#include<set>
using namespace std;
bool fncomp(int lhs,int rhs){
return lhs<rhs;
}
struct classcomp{
bool operator()(const int& lhs,const int& rhs){
return lhs<rhs;
}
};
int main(){
//set::set()函数 功能:构造set
set<int>first;//empty set of ints
int myints[]{1,2,3,4,5};
set<int>second(myints,myints+5);
//pointers used as iterator
set<int>third(second);//a copy of second
set<int>fourth(second.begin(),second.end());
//iterator ctor
set<int,classcomp>fifth;
//class as compare
bool(*fn_pt)(int,int)=fncomp;
set<int,bool(*)(int,int)>sixth(fn_pt);//function pointer as compare
return 0;
}
set::operator=()函数 功能:赋值set
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::operator=()函数 功能:赋值set
//set::size()函数 功能:集合中元素的数目
//set::begin()函数 功能:返回指向第一个元素的迭代器
//set::end()函数 功能:返回指向最后一个元素的迭代器
int myints[]={1998,11,1,2,3};
set<int>first(myints,myints+5);//set with 5 ints
set<int>second;//empty set
second=first;//now second contains the 5 ints
first=set<int>();//and first is empty
set<int>myset;
myset=second;
cout<<"Size of first:"<<int(first.size())<<endl;
cout<<"Size of second:"<<int(second.size())<<endl;
set<int>::iterator it;
cout<<"myset contains";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
}
运行结果
Size of first:0
Size of second:5
myset contains 1 2 3 11 1998
set::begin()函数 功能:返回指向第一个元素的迭代器
set::end()函数 功能:返回指向最后一个元素的迭代器
set::rbegin()函数 功能:返回指向集合中最后一个元素的反向迭代器
set::rend()函数 功能:返回指向集合中第一个元素的反向迭代器
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::rbegin()函数 功能:返回指向集合中最后一个元素的反向迭代器
//set::rend()函数 功能:返回指向集合中第一个元素的反向迭代器
int myints[]={1998,11,1};
set<int>myset(myints,myints+3);
set<int>::iterator it;
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
set<int>::reverse_iterator rit;
cout<<"myset contains:";
for(rit=myset.rbegin();rit!=myset.rend();rit++){
cout<<" "<<*rit;
}
cout<<endl;
}
运行结果
myset contains: 1 11 1998
myset contains: 1998 11 1
set::insert()函数 功能: 在集合中插入元素
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::insert()函数 功能: 在集合中插入元素
set<int>myset;
set<int>::iterator it;
pair<set<int>::iterator,bool>ret;
//set some initial values
for(int i=1;i<6;i++){
myset.insert(i*10);
//set:10 20 30 40 50
}
ret=myset.insert(20);//no new elements inserted
if(ret.second==false)it=ret.first;//it now points to elements 20
myset.insert(it,25);//max efficiency inserting
myset.insert(it,24);//max efficiency inserting
myset.insert(it,26);//no max efficiency inserting
int myints[]={1949,10,1};
//10 already in set,not inserted
myset.insert(myints,myints+3);
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
运行结果
myset contains: 1 10 20 24 25 26 30 40 50 1949
set::erase()函数 功能:删除集合中的元素
set::find()函数 功能:返回一个指向被查找元素的迭代器
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::erase()函数 功能:删除集合中的元素
//set::find()函数 功能:返回一个指向被查找元素的迭代器
set<int>myset;
set<int>::iterator it;
//insert some values
for(int i=1;i<11;i++){
myset.insert(i*10);
}
it=myset.begin();
it++;//it points now to 2o
myset.erase(it);
myset.erase(40);//找得到就删除,如果没有就删除,比如41
it=myset.find(60);
myset.erase(it,myset.end());
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
运行结果
myset contains: 10 30 50
set::clear()函数 功能:清除所有元素
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::clear()函数 功能:清除所有元素
set<int>myset;
set<int>::iterator it;
myset.insert(1998);
myset.insert(11);
myset.insert(3);
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
myset.clear();
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
myset.insert(1999);
myset.insert(2000);
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
运行结果
myset contains: 3 11 1998
myset contains:
myset contains: 1999 2000
set::empty()函数 功能:如果集合为空,返回true
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::empty()函数 功能:如果集合为空,返回true
set<int>myset;
myset.insert(1998);
myset.insert(11);
myset.insert(3);
myset.insert(1999);
cout<<"myset contains: ";
while(!myset.empty()){
cout<<" "<<*myset.begin();
myset.erase(myset.begin());
}
cout<<endl;
}
运行结果
myset contains: 3 11 1998 1999
set::count()函数 功能:返回某个值元素的个数
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::count()函数 功能:返回某个值元素的个数
set<int>myset;
//set some intial values
for(int i=1;i<5;i++){
myset.insert(i*3);//set:3 6 9 12
}
for(int i=0;i<10;i++){
cout<<i;
if(myset.count(i)>0)
cout<<" is an elements of myset"<<endl;
else
cout<<" is not an elements of myset"<<endl;
}
myset.insert(9);
myset.insert(9);
myset.insert(9);
cout<<myset.count(9)<<endl;//只输出一个
}
运行结果
0 is not an elements of myset
1 is not an elements of myset
2 is not an elements of myset
3 is an elements of myset
4 is not an elements of myset
5 is not an elements of myset
6 is an elements of myset
7 is not an elements of myset
8 is not an elements of myset
9 is an elements of myset
1
set::size()函数 功能:集合中元素的数目
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::size()函数 功能:集合中元素的数目
set<int>myset;
myset.insert(1998);
myset.insert(11);
myset.insert(3);
cout<<"myset contains: ";
while(!myset.empty()){
cout<<" "<<*myset.begin();
myset.erase(myset.begin());
}
cout<<endl;
cout<<"size "<<(int)myset.size()<<endl;
for(int i=1;i<11;i++)myset.insert(i);
cout<<"size "<<(int)myset.size()<<endl;
myset.insert(1998);
myset.insert(98);//插入自动排序
cout<<"size "<<(int)myset.size()<<endl;
myset.erase(6);
cout<<"size "<<(int)myset.size()<<endl;
cout<<"myset contains: ";
set<int>::iterator it;
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
运行结果
myset contains: 3 11 1998
size 0
size 10
size 12
size 11
myset contains: 1 2 3 4 5 7 8 9 10 98 1998
set::swap()函数 功能:交换两个集合变量
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::swap()函数 功能:交换两个集合变量
int myints[]={1,2,3,4,5,6,7,8,9};
set<int>first(myints,myints+3);
set<int>second(myints+3,myints+6);
set<int>::iterator it;
cout<<"before swap first contains:";
for(it=first.begin();it!=first.end();it++){
cout<<" "<<*it;
}
cout<<endl;
cout<<"before swap second contains:";
for(it=second.begin();it!=second.end();it++){
cout<<" "<<*it;
}
cout<<endl;
first.swap(second);
cout<<"first contains:";
for(it=first.begin();it!=first.end();it++){
cout<<" "<<*it;
}
cout<<endl;
cout<<"second contains:";
for(it=second.begin();it!=second.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
运行结果
before swap first contains: 1 2 3
before swap second contains: 4 5 6
first contains: 4 5 6
second contains: 1 2 3
set::get_allocator()函数 功能:返回集合分配器
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::get_allocator()函数 功能:返回集合分配器
set<int>myset;
int *p;
unsigned int i;
//allocate an array of 5 elements ysing myset's allocator
p=myset.get_allocator().allocate(6);
//assign some values to array
for(int i=0;i<6;i++){
p[i]=(i+1)*10;
}
cout<<"The allocated array contains:";
for(int i=0;i<6;i++){
cout<<" "<<p[i];
}
cout<<endl;
myset.get_allocator().deallocate(p,6);
}
运行结果
The allocated array contains: 10 20 30 40 50 60
set::key_comp()函数 功能:返回一个用于元素间比较的函数
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::key_comp()函数 功能:返回一个用于元素间比较的函数
set<int>myset;
set<int>::key_compare mycomp;
set<int>::iterator it;
int highest;
mycomp=myset.key_comp();
for(int i=0;i<=5;i++){
myset.insert(i);
}
cout<<"myset contains:";
highest=*myset.rbegin();
//set::rbegin()返回指向集合中最后一个元素的反向迭代器
it=myset.begin();
do{
cout<<" "<<*it;
}while(mycomp(*it++,highest));
cout<<endl;
}
运行结果
myset contains: 0 1 2 3 4 5
set::value_comp()函数 功能:返回一个用于比较元素间的值的函数
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::value_comp()函数 功能:返回一个用于
set<int>myset;
set<int>::value_compare mycomp;
set<int>::iterator it;
int highest;
mycomp=myset.value_comp();
for(int i=0;i<=5;i++){
myset.insert(i);
}
cout<<"myset contains:";
highest=*myset.rbegin();
//set::rbegin()返回指向集合中最后一个元素的反向迭代器
it=myset.begin();
do{
cout<<" "<<*it;
}while(mycomp(*it++,highest));
cout<<endl;
}
运行结果
myset contains: 0 1 2 3 4 5
set::lower_bound()函数 返回指向大于等于某值的第一个元素的迭代器
set::upper_bound()函数 返回指向大于等于某值的迭代器
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::lower_bound()函数 返回指向大于等于某值的第一个元素的迭代器
//set::upper_bound()函数 返回指向大于等于某值的迭代器
set<int>myset;
set<int>::iterator it ,itlow,itup;
for(int i=1;i<10;i++){
myset.insert(i*10);//10 20 30 40 50 60 70 80 90
}
itlow=myset.lower_bound(30);
itup=myset.upper_bound(60);
cout<<"itlow:"<<*itlow<<endl;
cout<<"itup:"<<*itup<<endl;
myset.erase(itlow,itup);//不删除itup指向的元素
//10 20 70 80 90
cout<<"myset contains:";
for(it=myset.begin();it!=myset.end();it++){
cout<<" "<<*it;
}
cout<<endl;
}
运行结果
itlow:30
itup:70
myset contains: 10 20 70 80 90
set::max_size()函数 返回集合能容纳的元素的最大限值
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::max_size()函数 返回集合能容纳的元素的最大限值
set<int>myset;
if(myset.max_size()>1000){
for(int i=0;i<1000;i++){
myset.insert(i);
}
cout<<"the set contains 1000 elements"<<endl;
}
else{
cout<<"the set could not contains 1000 elements"<<endl;
}
cout<<myset.max_size();
}
运行结果
the set contains 1000 elements
461168601842738790
set::equal_range()函数 功能:返回集合中与给定值相等的上下限的两个迭代器
#include<iostream>
#include<set>
using namespace std;
int main(){
//set::equal_range()函数 功能:返回集合中与给定值相等的上下限的两个迭代器
set<int>myset;
pair<set<int>::iterator,set<int>::iterator>ret;
for(int i=1;i<6;i++){
myset.insert(i*10);//set:10 20 30 40 50
}
ret=myset.equal_range(30);
cout<<"lower bound points to:"<<*ret.first<<endl;
cout<<"upper bound points to:"<<*ret.second<<endl;
}
运行结果
lower bound points to:30
upper bound points to:40
multiset::count()函数 与set::count()有区别
#include<iostream>
#include<set>
using namespace std;
int main(){
//multiset::count()函数 与set::count()有区别
int myints[]={1,2,3,3,3,3,3,4,5,6};
multiset<int>mymultiset(myints,myints+sizeof(myints));
cout<<"3 appears ";
cout<<(int)mymultiset.count(3);
cout<<" times in mymultiset"<<endl;
//与set的区别,其他函数大都相同
}
运行结果
3 appears 5 times in mymultiset
参考文献:《The Annotated STL Sources》侯捷