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

 

版权声明:本文为helloworldcode原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/helloworldcode/p/9526700.html