set集合的使用
set也是STL中比较常见的容器。set集合容器实现了红黑树的平衡二叉检索树的数据结构,它会自动调整二叉树的排列,把元素放到适当的位置。set容器所包含的元素的值是唯一的,集合中的元素按一定的顺序排列。
set集合的常用操作如下(注意要引入set头文件):
//集合测试 int main(){ set<int> s; set<int,greater<int>> ss; //从大到小存储 int tmp; for (int i = 0; i < 5; ++i) { tmp=rand()/10000000; s.insert(tmp); //往集合中插入元素 ss.insert(tmp); } s.insert(100); s.insert(100); s.insert(100); //set集合中的元素是唯一的,虽然插入这么多等值元素,但最终只会显示一个元素 ss.insert(100); //打印输出 for(set<int>::iterator it=s.begin(); it!=s.end(); it++){ cout<<*it<<" "; //依次输出84 100 168 171 180 195 } //即默认集合中的元素是从小到大排序的 cout<<endl; for(set<int,greater<int>>::iterator it=ss.begin(); it!=ss.end(); it++){ cout<<*it<<" "; //从大到小打印d } cout<<endl; set<int>::iterator ir=s.begin(); //ir=ir+3; //错误,不支持随机访问 //删除集合 while ( !s.empty() ) { set<int>::iterator it=s.begin(); s.erase(it); } cout<<endl; cout<<s.size()<<endl; return 0; }
以上案例中set存放的是简单的整数,如果是复杂的对象,我们要指定集合中存放元素比较的依据属性,利用仿函数去实现(上述中的set集合ss的声明中的greater<int>也是用仿函数实现的),如下案例:
class Student{ public: Student(int age,char *name){ this->age=age; strcpy(this->name,name); } /* * error: passing 'const Student' as 'this' argument discards qualifiers * getXXX()函数一般最好加上const, */ const char* getName() const{ return this->name; } const int getAge() const { return this->age; } public: char name[20]; int age; }; //仿函数 struct FuncStudent { bool operator()(const Student &left,const Student &right) const { if( left.getAge() < right.getAge() ){ return true; //如果左边的student的age小于右边,即从小到大排序 } else{ return false; } } }; int main(){ set<Student,FuncStudent> s; Student s1(20,"张三"); Student s2(50,"李四"); Student s3(24,"王五"); Student s4(32,"老六"); s.insert(s1); s.insert(s2); s.insert(s3); s.insert(s4); for(set<Student,FuncStudent>::iterator it=s.begin(); it !=s.end(); it++){ cout<<it->getName()<<"\t"<<it->getAge()<<endl; } return 0; }
此时又有一个问题,如果插入的元素是一个年龄相同,但姓名不同的对象的时候(测试可以通过,但结果中没有该元素),这个时候需要注意insert()的返回值了,可以用返回值来检测,具体操作如下:
int main(){ set<Student,FuncStudent> s; Student s1(20,"张三"); Student s2(50,"李四"); Student s3(24,"王五"); Student s4(32,"老六"); //insert()函数的返回值 typedef pair<iterator,bool> _Pairib pair<set<Student,FuncStudent>::iterator,bool> pair1=s.insert(s1); //对插入检查是否成功 if ( pair1.second ==true ) { cout<<"s1插入成功"<<endl; }else{ cout<<"s1插入失败"<<endl; } s.insert(s2); s.insert(s3); s.insert(s4); //如果插入一个年龄相同的数据 Student s5(20,"test"); pair<set<Student,FuncStudent>::iterator,bool> pair2=s.insert(s5); //插入不成功 if ( pair2.second ==true ) { cout<<"s5插入成功"<<endl; }else{ cout<<"s5插入失败"<<endl; } for(set<Student,FuncStudent>::iterator it=s.begin(); it !=s.end(); it++){ cout<<it->getName()<<"\t"<<it->getAge()<<endl; } return 0; }
结果如下所示:
s1插入成功
s5插入失败
张三 20
王五 24
老六 32
李四 50