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


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

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

1 插入

#include<iostream>
#include<set>
using namespace std;

void printSetInt(set <int>& s) {
    set<int>::iterator it = s.begin();
    for (; it != s.end(); it++)
        cout << *it << " ";
    cout << endl;
}
void test1() {
    set<int> 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);
}
int main() {
    test1();
    return 0;
}

在这里插入图片描述

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

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

使用仿函数实现

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

但是出错,而作者视频里面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;
    }
};

常量成员函数
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<int, Mycompare> &s) {
    set<int, Mycompare>::iterator it = s.begin();
    for (; it != s.end(); it++)
        cout << *it << " ";
    cout << endl;
}
void test1() {
    //set<int> s;//默认升序
    set<int, Mycompare> s;//set<int,排序规则> 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);

}
int main() {
    test1();
    return 0;
}

在这里插入图片描述

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<Person, Mycompare2>& s) {
    set<Person, Mycompare>::iterator it = s.begin();
    for (; it != s.end(); it++)
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
    cout << endl;
}
void test2() {
    set<Person, Mycompare2> 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;
}

//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;
public:
    
    friend class Mycompare2;//Mycompare2要访问,Person 的私有变量m_Name、m_Age
    friend void printSetPerson(set<Person, Mycompare2>& s);

完整代码

//自定义数据类型
class Person {
public:
    
    friend class Mycompare2;//Mycompare2要访问,Person 的私有变量m_Name、m_Age
    friend void printSetPerson(set<Person, Mycompare2>& 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<Person, Mycompare2>& s) {
    set<Person, Mycompare2>::iterator it = s.begin();
    for (; it != s.end(); it++)
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
    cout << endl;
}
void test2() {
    set<Person, Mycompare2> 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);
}

输出没毛病,但 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<int>::iterator it = s.find(5);
if (it != s.end())
    cout << *it << endl;

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

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

5 上下限 upper_bound()、lower_bound()

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

   set<int>::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;

在这里插入图片描述

6 对组(pair)

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

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

    pair<set<int>::iterator, set<int>::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;

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R-G-B

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值