• set容器


    一.摘要

    简介:

    • 所有元素都会在插入时自动被排序

    本质:

    • set/multiset属于关联式容器,底层结构是用二叉树实现。

    set和multiset区别

    • set不允许容器中有重复的元素
    • multiset允许容器中有重复的元素

    二.构造函数

     函数原型:

    set<T> st; //默认构造函数:
    set(const set &st); //拷贝构造函数

    示例代码:

     1 /*set构造函数*/
     2 #include<iostream>
     3 #include<ctime>
     4 #include<set>
     5 using namespace std;
     6 void printSet(set<int>&s) {
     7     cout << "set:";
     8     for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
     9         cout << *it << " ";
    10     }
    11     cout << endl;
    12 }
    13 void printMultiset(multiset<int>&s) {
    14     cout << "multiset:";
    15     for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
    16         cout << *it << " ";
    17     }
    18     cout << endl;
    19 }
    20 int main() {
    21     int tmp;
    22     srand((unsigned)time(NULL));
    23     set<int>s1;    //set<T> st; //默认构造函数:
    24     multiset<int>ms1;
    25     for (int i = 0; i < 5; i++) {
    26         tmp = rand();
    27         //set不可以添加重复数据,multiset可以添加重复数据
    28         s1.insert(tmp);
    29         s1.insert(tmp);//插两次
    30         ms1.insert(tmp);
    31         ms1.insert(tmp);//插两次
    32     }
    33     printSet(s1);
    34     printMultiset(ms1);
    35     set<int>s2(s1);    //set(const set &st); //拷贝构造函数
    36     multiset<int>ms2(ms1);
    37     printSet(s2);
    38     printMultiset(ms2);
    39     system("pause");
    40     return 0;
    41 }
    set的构造函数

    运行结果:

    二.大小和交换

     函数原型:

    size(); //返回容器中元素的数目
    empty(); //判断容器是否为空
    swap(st); //交换两个集合容器

    示例代码:

     1 /*set大小和交换*/
     2 #include<iostream>
     3 #include<ctime>
     4 #include<set>
     5 using namespace std;
     6 void printSet(set<int>&s) {
     7     for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
     8         cout << *it << " ";
     9     }
    10     cout << endl;
    11 }
    12 int main() {
    13     srand((unsigned)time(NULL));
    14     set<int>s1;
    15     for (int i = 0; i < 5; i++) {
    16         s1.insert(rand());
    17     }    
    18     if (s1.empty()) {    //empty(); //判断容器是否为空
    19         cout << "s1为空!";
    20     }
    21     else {
    22         cout << "s1不为空!" << endl;
    23         cout << "s1的大小为:" << s1.size() << endl;    //size(); //返回容器中元素的数目
    24     }
    25     cout << "s1:";
    26     printSet(s1);
    27     set<int>s2;
    28     for (int i = 0; i < 5; i++) {
    29         s2.insert(rand());
    30     }
    31     cout << "s2:";
    32     printSet(s2);
    33     s1.swap(s2);    //swap(st); //交换两个集合容器
    34     cout << "交换后:" << endl;
    35     cout << "s1:";
    36     printSet(s1);
    37     cout << "s2:";
    38     printSet(s2);
    39     system("pause");
    40     return 0;
    41 }
    set的大小和交换

    运行结果:

    二.插入和删除

     函数原型:

    insert(elem); //在容器中插入元素。
    clear(); //清除所有元素
    erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
    erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
    erase(elem); //删除容器中值为elem的元素。

    示例代码:

     1 /*set容器的插入和删除*/
     2 #include<iostream>
     3 #include<ctime>
     4 #include<set>
     5 using namespace std; 
     6 void printSet(set<int>&s){
     7     for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
     8         cout << *it << " ";
     9     }
    10     cout << endl;
    11 }
    12 int main() {
    13     srand((unsigned)time(NULL));
    14     set<int>s1;
    15     for (int i = 0; i < 10; i++) {
    16         s1.insert(rand());    //insert(elem); //在容器中插入元素。
    17     }
    18     s1.insert(18888);    //插入一个18888
    19     printSet(s1);
    20     s1.erase(s1.begin());    //erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
    21     cout << "删除第一个元素之后:" << endl;
    22     printSet(s1);
    23     s1.erase(18888);    //erase(elem); //删除容器中值为elem的元素。
    24     cout << "删除set容器中的18888之后:" << endl;
    25     printSet(s1);
    26     s1.erase(++s1.begin(), --s1.end());    //erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
    27     cout << "删除第二到倒数第一个元素之后" << endl;
    28     printSet(s1);
    29     s1.clear();    //clear(); //清除所有元素
    30     cout << "清除所有元素之后:" << endl;
    31     printSet(s1);
    32     system("pause");
    33     return 0;
    34 }
    set的插入和删除

    运行结果:

    二.查找和统计

     函数原型:

    find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
    count(key); //统计key的元素个数

    示例代码:

     1 /*set容器的插入和删除*/
     2 #include<iostream>
     3 #include<ctime>
     4 #include<set>
     5 using namespace std;
     6 void printSet(set<int>&s){
     7     for (set<int>::iterator it = s.begin(); it != s.end(); it++) {
     8         cout << *it << " ";
     9     }
    10     cout << endl;
    11 }
    12 int main() {
    13     srand((unsigned)time(NULL));
    14     set<int>s1;
    15     for (int i = 0; i < 10; i++) {
    16         s1.insert(i);    //insert(elem); //在容器中插入元素。
    17     }
    18     s1.insert(8);
    19     printSet(s1);
    20     set<int>::iterator pos = s1.find(7);    //find(key); //查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end();
    21     if (pos != s1.end()) {
    22         cout << "找到元素:" << *pos << endl;
    23     }
    24     else {
    25         cout << "不存在元素:7" << endl;
    26     }
    27     cout << "元素7的个数是:" << s1.count(7) << endl;    //count(key); //统计key的元素个数
    28     cout << "元素8的个数是:" << s1.count(8) << endl;    //结果为1是因为set中没哟重复的元素
    29     cout << "元素666的个数是:" << s1.count(666) << endl;
    30     system("pause");
    31     return 0;
    32 }
    set的查找和统计

    运行结果:

    三.更改排序规则

     使用方法:

      添加自定义类->在类中重载小括号 () -> set的参数列表另加上自定义类类名;

    示例代码:

     1 /*set容器的排序规则*/
     2 #include<iostream>
     3 #include<ctime>
     4 #include<set>
     5 using namespace std;
     6 class MyCompare {
     7 public:
     8     bool operator()(int x, int y) {//重载操作()
     9         return x > y;    //降序排列
    10     }
    11 };
    12 void printSet(const set<int, MyCompare>se) {
    13     for (set<int, MyCompare>::iterator it = se.begin(); it != se.end(); it++) {
    14         cout << *it << " ";
    15     }
    16     cout << endl;
    17 }
    18 int main() {
    19     srand((unsigned)time(NULL));
    20     set<int, MyCompare>se;    //因为参数列表不能是函数,所以要自定义类
    21     for (int i = 0; i < 10; i++) {
    22         se.insert(rand());
    23     }
    24     printSet(se);
    25     system("pause");
    26     return 0;
    27 }
    set更改排序规则

    运行结果:

    四.自定义数据类型指定排序规则

    使用方法:

    和上面的差不多,只需要改一下set的参数列表和防函数的排序规则

    示例代码:

     1 /*set容器自定义数据类型指定排序规则*/
     2 #include<iostream>
     3 #include<string>
     4 #include<set>
     5 using namespace std;
     6 class Person {    //自定义数据类型
     7 public:
     8     Person(string t_name, int t_age) {
     9         this->name = t_name;
    10         this->age = t_age;
    11     }
    12     string name;
    13     int age;
    14 };
    15 class MyCompare {
    16 public:
    17     bool operator()(const Person &x, const Person &y) {//重载操作()
    18         return x.age > y.age;    //降序排列
    19     }
    20 };
    21 void printSet(const set<Person, MyCompare>se) {
    22     for (set<Person, MyCompare>::iterator it = se.begin(); it != se.end(); it++) {
    23         cout << (*it).name << " " << (*it).age << endl;
    24     }
    25 }
    26 int main() {
    27     set<Person, MyCompare>se;    //因为参数列表不能是函数,所以要自定义类
    28     Person p1("mzb", 21), p2("cxy", 20), p3("zyf", 19), p4("cxt", 22), p5("tcj", 20);
    29     se.insert(p1), se.insert(p2), se.insert(p3), se.insert(p4),se.insert(p5);
    30     printSet(se);
    31     cout << "p5的年龄和p2的年龄相同,插入失败!" << endl;
    32     system("pause");
    33     return 0;
    34 }
    set的自定义数据类型指定排序规则

    运行结果:

     

    注意事项:

      需要注意的是,上面的 “cxy” 和 “tjc” 由于年龄相同无法插入,当然你会想到我可以通过修改防函数,如果年龄相同我就对姓名进行排序(如下图),但是这是不行的,至于为什么不行,我也不太清楚,源码目前还看不懂;

    五.总结

       set容器的操作接口相对来说不多,使用起来也比较简单(个人感觉没啥用,还不如直接存入再用sort排序),但是还需要注意以下注意事项:

    • 自定义排序规则时的仿函数的类名要放在最后,否则就会报错;
    • set容器插入函数返回的是一个 pair对组(第一个参数是迭代器,第二个是布尔类型变量)。
  • 相关阅读:
    【新闻发布系统】登录和注销的实现
    【新闻发布系统】项目文档
    JSP九大内置对象
    JDBC数据库连接技术
    使用SQLyog连接MySQL数据库
    MySql--学习成长过程
    MYSQL--学习记录
    MYSQL
    GIT的使用方法
    java 表单验证
  • 原文地址:https://www.cnblogs.com/chasemeng/p/12890439.html
Copyright © 2020-2023  润新知