只读迭代器,插入后,就是有序的了,不能修改值,
因为插入如完毕,已经是有序的了,修改值就变成无序了;
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实现,完全没问题
严重性 代码 说明 项目 文件 行 禁止显示状态 错误 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;