• C++ STL(八)容器_set和multiset


    set(集合)是一个集合容器,容器中的元素是唯一的,元素即是键值又是实值,集合中的元素按一定的顺序排序.属于关联式容器的一种.

    元素插入过程是按排序规则插入,不能指定插入位置.

    它不支持随机存取元素,不能使用数组[]和at方式进行访问.

    set与multiset区别:set每个元素值在容器中只能出现一次,而multiset可以出现多次

    所需头文件:#include<set>

    构造函数:

     1     //set
     2     set<int> setA; //构造个空的set
     3     set<int> setB(setA); //通过setA拷贝构造一个set (setB=setA)
     4     int nArray[] = {1,2,3};
     5     int nLeng = sizeof(nArray)/sizeof(int);
     6     set<int> setC(nArray, nArray+nLeng); //通过数组拷贝构造一个setC (setC={1,2,3})
     7     //使用迭代器构造    
     8     set<int> dIt(setC.begin(),setC.end()); //正向迭代器方式构造set (dIt={1,2,3,4,5})
     9     set<int> dRit(setC.rbegin(), setC.rend()); //反向迭代器方式构造set (dRit={5,4,3,2,1})
    10     
    11     //multiset
    12     multiset<int> multisetA; //构造个空的multiset
    13     multiset<int> multisetB(multisetA); //通过multisetA拷贝构造一个multiset (multisetB=multisetA)
    14     nLeng = sizeof(nArray)/sizeof(int);
    15     multiset<int> multisetC(nArray, nArray+nLeng); //通过数组拷贝构造一个multisetC (multisetC={1,2,3})
    16     //使用迭代器构造
    17     multiset<int> dItM(multisetC.begin(), multisetC.end()); //正向迭代器方式构造multisetC (dItM={1,2,3,4,5})
    18     multiset<int> dRiM(multisetC.rbegin(), multisetC.rend()); //反向迭代器方式构造multisetC (dRiM={5,4,3,2,1})
    19 
    20     return;
    构造函数

    增加元素操作:

    注意:set中元素是唯一的,无法插入重复的元素.multiset中可以插入重复的元素. 二种容器插入后都会自动进行排序

     1     //set中元素是唯一的,无法插入重复的元素
     2     set<int> setA;
     3     setA.insert(1);
     4     setA.insert(2);
     5     setA.insert(3);
     6     pair<set<int>::iterator,int> pairSet;
     7     pairSet = setA.insert(2); //此时由于容器中己有元素值2,就不会插入新元素2. 此时setA={1,2,3}
     8     //根据返回值pair的第二个参数可以发现插入失败
     9     if(pairSet.second == 0)
    10     {
    11         printf("set插入失败
    ");
    12     }
    13     else if(pairSet.second == 1)
    14     {
    15         printf("set插入成功
    ");
    16     }
    17     //迭代器方式插入
    18     setA.insert(setA.end(),4); //setA={1,2,3,4}
    19     set<int> setB;
    20     setB.insert(setA.begin(), setA.end()); //把setA中所有元素插入到setB中
    21 
    22 
    23     //multiset中可以插入重复的元素
    24     multiset<int>::iterator it;
    25     multiset<int> multisetA;
    26     multisetA.insert(1); 
    27     multisetA.insert(2); 
    28     it = multisetA.insert(3); //it指向插入后新元素3的位置
    29     it = multisetA.insert(2); //it指向插入后新元素2的位置,证明multiset可以插入重复的元素
    30     //迭代器方式插入
    31     multisetA.insert(multisetA.end(),4); //multisetA={1,2,2,3,4}
    32     multiset<int> multisetB;
    33     multisetB.insert(multisetA.begin(), multisetA.end()); //把multisetA中所有元素插入到multisetB中
    34 
    35     //注意:set的insert()返回的是pair,而multiset返回的是指向插入后新元素位置的迭代器
    36     return;
    增加元素操作

    删除元素操作:

    注意:set中元素是唯一的,所以删除时只会删除1个元素.multiset中元素可以是重复的,所以根据key进行删除时只要相同的都会批量删除

     1     //set中元素是唯一的,所以删除时只会删除1个元素
     2     set<int> setA;
     3     setA.insert(1);
     4     setA.insert(2);
     5     setA.insert(3);
     6 
     7     setA.erase(1); //删除元素1  setA={2,3}
     8     setA.erase(setA.begin()); //使用迭代器删除指向开始位置的元素 setA={3}
     9     setA.clear(); //清除所有元素
    10 
    11 
    12     //multiset中元素可以是重复的,所以根据key进行删除时只要相同的都会批量删除
    13     multiset<int> multisetA;
    14     multisetA.insert(1);
    15     multisetA.insert(1);
    16     multisetA.insert(2);
    17 
    18     multisetA.erase(1); //所有元素值为1的元素都被删除了,最终multisetA={2}
    19     multisetA.erase(multisetA.begin()); //使用迭代器删除指向开始位置的元素 multisetA={}
    20     multisetA.clear(); //清除所有元素
    21 
    22     return;
    删除元素操作

    获取大小:

    empty()  返回是否为空

    size()     返回大小

    max_size()  返回所能存储的最大元素个数,这是由系统自动定义的值

     1     //set
     2     set<int> setA;
     3     bool bEmpty = setA.empty(); //bEmpty = true
     4     int nSize = setA.size();    //nsize = 0
     5     setA.insert(1);
     6     bEmpty = setA.empty(); //bEmpty = false
     7     nSize = setA.size();  //nSize = 1
     8     int nMaxSize = setA.max_size(); //nMaxSize = 214748364 所能存储的最大元素个数,这是由系统自动定义的值
     9 
    10     //mulitset
    11     multiset<int> multisetA;
    12     bEmpty = multisetA.empty(); //bEmpty = true
    13     nSize = multisetA.size();    //nsize = 0
    14     multisetA.insert(1);
    15     multisetA.insert(1);
    16     bEmpty = multisetA.empty(); //bEmpty = false
    17     nSize = multisetA.size();  //nSize = 2
    18     nMaxSize = multisetA.max_size(); 
    19 
    20     return;
    获取大小

    查找操作:

    find()  根据元素值进行查找,返回第一个找到的迭代器

    count(key) 根据元素值进行查找,返回元素个数. 注意: set返回的只有可能是0或者1,而multiset返回的可能是0和>0的元素个数

    lower_bound(elem) 返回第一个>=elem元素的迭代器

    upper_bound(elem) 返回第一个> elem元素的迭代器

    equal_range(elem) 返回容器中与elem相等的包含上下限二个迭代器的pair

     1     set<int> setInt;
     2     setInt.insert(11);
     3     setInt.insert(13);
     4     setInt.insert(22);
     5     setInt.insert(9);
     6     setInt.insert(7);
     7 
     8     //find 根据元素值进行查找,返回第一个找到的迭代器
     9     set<int>::iterator it = setInt.find(9);
    10     int nValue = *it; //nValue = 9
    11 
    12     //count 根据元素值进行查找,返回元素个数
    13     //因为set中元素是唯一的,所以count()返回的只有可能是0或者是1
    14     //而multiset中元素值可以是重复的,所以count()值可以是0,或者>=1
    15     int nCount = setInt.count(99); //没有找到元素值为99的元素,nCount=0
    16     nCount = setInt.count(7); //nCount = 1
    17 
    18     //lower_bound(elem) 返回第一个>=elem元素的迭代器
    19     //upper_bound(elem) 返回第一个> elem元素的迭代器
    20     set<int>::iterator itLower = setInt.lower_bound(13); //*itLower = 13
    21     set<int>::iterator itUpper = setInt.upper_bound(13); //*itUpper = 22
    22 
    23     //equal_range(elem) 返回容器中与elem相等的包含上下限二个迭代器的pair
    24     //pair是个对组,包含二个迭代器,first与second
    25     //pair.first 查找的元素值所在的迭代器
    26     //pair.second 查找的元素值所在的下一个迭代器
    27     pair<set<int>::iterator, set<int>::iterator> itPair = setInt.equal_range(13);
    28     set<int>::iterator itFirst = itPair.first; //*itFirst = 13
    29     set<int>::iterator itSecond = itPair.second; //*itSecond = 22
    30 
    31     return;
    查找操作

    排序操作:

    1.自动排序: 定义set和multiset时使用缺省排序或者显示指明容器排序方式. 注意:只能排序基本数据类型

     1     //自动排序,只能排序基本数据类型
     2     set<int> setA; //set和multiset使用缺省的排序方式,也就是升序排序
     3     set<int,less<int>> setLess; //setB和setA是等价的都是升序排序
     4     set<int,greater<int>> setGreater; //使用降序排序
     5 
     6     setA.insert(3);
     7     setA.insert(1);
     8     setA.insert(2);  //此时由于setA使用默认的升序排序,setA={1,2,3}
     9 
    10     setLess.insert(3);
    11     setLess.insert(1);
    12     setLess.insert(2); //此时由于setB和setA一样也是使用升序排序,setLess={1,2,3}
    13 
    14     setGreater.insert(3);
    15     setGreater.insert(1);
    16     setGreater.insert(2); //此时由于setGreater使用降序排序,setGreater={3,2,1}
    17 
    18     return;
    自动排序

    2.编写排序函数排序:

    学生包含学号,姓名属性,现要求插入几个学生对象到set容器中,使得容器中的学生按学号的升序排列.

     1 class CStudent
     2 {
     3 public:
     4     CStudent(int nId, string strName)
     5     {
     6         m_nId = nId;  //学号
     7         m_strName = strName; //学生名字
     8     }
     9 public:
    10     int m_nId;
    11     string m_strName;
    12 };
    学生对象
    1 struct StuFunctor
    2 {
    3     bool operator()(const CStudent &stu1, const CStudent &stu2)
    4     {
    5         return (stu1.m_nId<stu2.m_nId); //根据nId学号进行升序排列
    6         //return (stu1.m_nId>stu2.m_nId); //根据nId学号进行降序排列
    7     }
    8 };
    学生排序函数
     1 inline void SortByFunction()
     2 {
     3     //函数对象functor的用法
     4     //学生包含学号,姓名属性,现要求插入几个学生对象到
     5     //set容器中,使得容器中的学生按学号的升序排列.
     6     set<CStudent,StuFunctor> setStu; //定义set时指定使用自定义排序函数
     7     setStu.insert(CStudent(3,"小张"));
     8     setStu.insert(CStudent(1,"小李"));
     9     setStu.insert(CStudent(5,"小王"));
    10     setStu.insert(CStudent(2,"小刘"));
    11     set<CStudent,StuFunctor>::iterator it = setStu.begin();
    12     for (it; it!=setStu.end(); ++it)
    13     {
    14         cout<<it->m_nId <<":"<<it->m_strName.c_str()<<endl;
    15     }
    16 
    17     getchar();
    18     return;
    19 }
    演示部份

    输出结果:

  • 相关阅读:
    解决VM 安装Ubuntu64与 Device/Credential Guard 不兼容,显示不支持64位系统
    WPF处理内容溢出
    .NET Standard 2.0 是什麼?可以吃嗎?
    C#.Net]启动外部程序的几种常用方法汇总
    在C#中接收系统屏幕锁定和解锁的事件
    C#.Net]启动外部程序的几种常用方法汇总
    MongoDB索引的使用
    读取xml并将节点保存到Excal
    开学后的第一篇
    续并查集学习笔记——Gang团伙题解
  • 原文地址:https://www.cnblogs.com/fzxiaoyi/p/12107890.html
Copyright © 2020-2023  润新知