• set容器 集合 常用 API操作 (只读迭代器)



    只读迭代器,插入后,就是有序的了,不能修改值,
    因为插入如完毕,已经是有序的了,修改值就变成无序了;

    set内部使用平衡二叉树管理

    1 插入

    #include
    #include
    using namespace std;
    
    void printSetInt(set & s) {
        set::iterator it = s.begin();
        for (; it != s.end(); it++)
            cout << *it << " ";
        cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    void test1() {
        set s;
        s.insert(1);
        s.insert(4);
        s.insert(5);
        s.insert(2);
        s.insert(3);
        s.insert(6);
    
        //打印
        cout << "大小:" << s.size() << endl;
        printSetInt(s);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    int main() {
        test1();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    2 修改排序规则(默认升序)

    set s;//默认升序
    set s; //默认升序,支持自定义排序规则

    使用仿函数实现

    //仿函数:重载函数调用运算符()的类;;;定义排序规则
    class Mycompare {
    public:
        bool operator()(int v1, int v2){//重载运算符
            return v1 > v2;//降序排列
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    但是出错,而作者视频里面qt实现,完全没问题

    C++编译器错误C3848 解决方法参考

    在这里插入图片描述

    严重性 代码 说明 项目 文件 行 禁止显示状态 错误 C3848 具有类型“const Mycompare”的表达式会丢失一些 const-volatile 限定符以调用“bool Mycompare::operator ()(int,int)” set C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.32.31326\include\xutility 1451 <\foont>

    报错原因:

    在使用MyCompare时存在const属性,但是调用该MyCompare的表达式 bool operator()(int v1, int v2)不具有const属性,丢失const,所以无法通过编译。

    解决办法:
    在重载函数名后面加上那个 const

    class Mycompare {
    public:
        bool operator()(int v1, int v2) const{
            return v1 > v2;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    常量成员函数
    const int& myData::getData() const { return data; }

    function()后面加const叫做const function,只能在class中作为成员函数使用,可以由const object 或者 non-const object 调用,但const object 只能调用const member function。不修改类中成员变量的函数都可以声明为const member function。

    const 成员函数可以与 non-const 成员函数重载。

    function()前面加const表示返回值是const,可以在任何地方用,只需要接收变量是const就可以。

    完成代码

    //仿函数:重载函数调用运算符()的类;;;定义排序规则
    class Mycompare {
    public:
        bool operator()(int v1, int v2)const{//重载运算符
            return v1 > v2;//降序排列
        }
    };
    
    
    void printSetInt(set &s) {
        set::iterator it = s.begin();
        for (; it != s.end(); it++)
            cout << *it << " ";
        cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    void test1() {
        //set s;//默认升序
        set s;//set s; //默认升序,这里可以修改排序规则,仿函数实现
        s.insert(1);
        s.insert(4);
        s.insert(5);
        s.insert(2);
        s.insert(3);
        s.insert(6);
    
        //打印
        cout << "大小:" << s.size() << endl;
        printSetInt(s);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    int main() {
        test1();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    3 set 自定义数据类型,必须修改排序规则

    自定义数据类型Person

    //自定义数据类型
    class Person {
    public:
        Person(string name,int age) {
            this->m_Name = name;
            this->m_Age = age;
        }
        string m_Name;
        int m_Age;
    };
    
    //按照年龄排序
    class Mycompare2 {
    public:
        bool operator()(Person p1,Person p2) const{
            return p1.m_Age < p2.m_Age;
        }
    };
    
    void printSetPerson(set& s) {
        set::iterator it = s.begin();
        for (; it != s.end(); it++)
            cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
        cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    void test2() {
        set s;
        s.insert(Person("张",60));
        s.insert(Person("刘",25));
    
        //set 不允许两个元素有相同的键值。
        //姓名不同,年龄相同;年龄相同,年龄不同;;;看看结果那些会被去重
        Person p1("赵",26), p2("孙",26),p3("孙",22);
        s.insert(p1);
        s.insert(p2);
        s.insert(p3);
    
        //打印
        cout << "大小:" << s.size() << endl;
        printSetPerson(s);
    }
    int main() {
        test2();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    //set 不允许两个元素有相同的键值。
    //姓名不同,年龄相同;年龄相同,年龄不同;;;看看结果那些会被去重
    Person p1(“赵”,26), p2(“孙”,26),p3(“孙”,22);

    结果发现,年龄相同的p2(“孙”,26)被去重了;

    因为,排序规则是按照年龄排序。

    在这里插入图片描述

    3.1 将nane、age改成私有变量

    将nane、age改成私有变量;
    print、compare 要友元

    private:
        string m_Name;
        int m_Age;
    
    • 1
    • 2
    • 3
    public:
        
        friend class Mycompare2;//Mycompare2要访问,Person 的私有变量m_Name、m_Age
        friend void printSetPerson(set& s);
    
    • 1
    • 2
    • 3
    • 4

    完整代码

    //自定义数据类型
    class Person {
    public:
        
        friend class Mycompare2;//Mycompare2要访问,Person 的私有变量m_Name、m_Age
        friend void printSetPerson(set& s);
    
        Person(string name,int age) {
            this->m_Name = name;
            this->m_Age = age;
        }
    private:
        string m_Name;
        int m_Age;
    };
    
    //按照年龄排序
    class Mycompare2 {//因为要访问,Person 的私有变量m_Name、m_Age,将Mycompare2类设为有元
    public:
        bool operator()(Person p1,Person p2) const{
            return p1.m_Age < p2.m_Age;
        }
    };
    
    void printSetPerson(set& s) {
        set::iterator it = s.begin();
        for (; it != s.end(); it++)
            cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
        cout << endl;
    }
    void test2() {
        set s;
        s.insert(Person("张",60));
        s.insert(Person("刘",25));
    
        //set 不允许两个元素有相同的键值。
        //姓名不同,年龄相同;年龄相同,年龄不同;;;看看结果那些会被去重
        Person p1("赵",26), p2("孙",26),p3("孙",22);
        s.insert(p1);
        s.insert(p2);
        s.insert(p3);
    
        //打印
        cout << "大小:" << s.size() << endl;
        printSetPerson(s);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    输出没毛病,但 prin依然显示不可访问私有变量
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    4 s.find()、count()

    if(s.find(p3) != s.end())
    cout << p3.m_Name <<" "<< p3.m_Age << endl;

    在这里插入图片描述
    //find(key);//查找键 key 是否存在,若存在,返回该键的元素的迭代器;若不存在,返回 set.end();

    //查找

    set::iterator it = s.find(5);
    if (it != s.end())
        cout << *it << endl;
    
    • 1
    • 2
    • 3

    在这里插入图片描述
    count(key);//查找键 key 的元素个数

    set的键值不重复,那么结果只能是0或1;
    在这里插入图片描述

    5 上下限 upper_bound()、lower_bound()

    // upper_bound(keyElem);//下限,返回第一个key>keyElem元素的迭代器。
    // equal_range(keyElem);//上限,返回容器中key与keyElem相等的上下限的两个迭代器
    在这里插入图片描述

       set::iterator it;
        it = s.lower_bound(50);
        if (it != s.end())
            cout <<"\n下限lower_bound(50)为:"<< * it << endl;
    
        it = s.upper_bound(50);
        if (it != s.end())
            cout << "上限upper_bound(50)为:" << *it << endl;
    
        it = s.lower_bound(35);
        if (it != s.end())
            cout << "\n下限lower_bound(35)为:" << *it << endl;
    
        it = s.upper_bound(35);
        if (it != s.end())
            cout << "上限upper_bound(35)为:" << *it << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述

    6 对组(pair)

    equal_range(keyElem);//返回容器中 key 与 keyElem 相等的上下限的两个迭代器

    同时返回,上下限两个迭代器,用对组接收返回值

        pair::iterator, set::iterator> pa;
        pa = s.equal_range(50);//同时返回,上下限两个迭代器,用对组接收返回值
        if (pa.first != s.end())
            cout << "\n下限lower_bound(50)为:" << *(pa.first) << endl;
        if (pa.second != s.end())
            cout << "上限upper_bound(50)为:" << *(pa.second) << endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

  • 相关阅读:
    【Rust日报】2022-09-07 Wasmtime 将在 9月20 号 发布 1.0 版本
    04训练——基于YOLO V8的自定义数据集训练——在windows环境下使用pycharm做训练-1总体步骤
    ORB-SLAM2实时稠密地图,解决运行报段错误(核心已转储)运行数据集时出现段错误,出现可视化界面后闪退(添加实时彩色点云地图+保存点云地图)
    Java类加载器
    实验七 Python面向对象程序设计
    【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问
    农历版的FullCalendar插件
    利用OpenCV的函数imwrite()保存图像到硬盘
    Oracle 11g DataGuard 搭建笔记(Windows Server 2016)
    EasyAR使用
  • 原文地址:https://blog.csdn.net/m0_51233386/article/details/126513960