C++ STL set容器详解
C++ set容器set/multiset容器的概念1.set的构造和赋值2.set的大小和交换3.set的插入和删除4.set的查找和统计5.set和multiset的区别6.pair对组的创建7.set容器的排序规则set/multiset容器的概念特点:所有元素都会在插入时自动被排序本质:set/multiset属于关联式容器,底层结构是用二叉树实现的set和multiset的区别:set不
C++ set容器
set/multiset容器的概念
特点:所有元素都会在插入时自动被排序
本质:set/multiset属于关联式容器,底层结构是用二叉树实现的
set和multiset的区别:
set不允许容器中有重复的元素
multiset允许容器中有重复的元素
注意:使用set或multiset容器时需要包含头文件
#include<set>
1.set的构造和赋值
构造:
set<T> st;
//默认构造
set(const set& st);
//拷贝构造
赋值:
set& operator=(const set& st);
重载赋值运算符
在测试之前,我们先创建一个打印输出的函数,之后在测试时经常用到
void printSet(const set<int>& st)
{
cout << "打印set容器:" ;
for (set<int>::iterator it = st.begin(); it != st.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
测试案例:
void text()
{
set<int> s1; //默认构造
//set插入数据只有insert的方式
s1.insert(20);
s1.insert(30);
s1.insert(10);
//s1.insert(10); //容器中已经有相同的元素,插入失败,但并不报错
//打印s1,是按升序排序好的顺序打印的
printSet(s1);
set<int> s2(s1); //拷贝构造
set<int> s3;
s3 = s1; //重载的赋值运算符
}
测试结果:
2.set的大小和交换
函数原型:
size();
//返回容器中元素个数
empty();
//判断容器是否为空,为空返回1,否则返回0
swap();
//交换两个容器
测试案例:
void text()
{
set<int> s1, s2;
//empty()
if (s1.empty()) //如果s1为空
{
s1.insert(1);
s1.insert(5);
s1.insert(3);
}
if (s2.empty())
{
s2.insert(10);
s2.insert(50);
s2.insert(30);
s2.insert(80);
}
//size()
cout << "s1的大小为:" << s1.size() << endl;
cout << "s2的大小为:" << s2.size() << endl;
//swap()
cout << "交换前:" << endl;
printSet(s1);
printSet(s2);
s1.swap(s2);//交换s1和s2
cout << "交换后:" << endl;
printSet(s1);
printSet(s2);
}
测试结果:
3.set的插入和删除
函数原型:
insert();
//在容器中插入元素
erase(pos);
//删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(elem);
//删除容器中值为elem的元素
erase(begin,end);
//删除迭代器区间为[beg,end)中的所有元素,返回下一个元素的迭代器
clear();
//清空容器中所有元素
测试案例:
void text()
{
set<int> s;
//insert()
s.insert(10);
s.insert(8);
s.insert(15);
s.insert(2);
printSet(s);
//erase()
s.erase(s.begin()); //删除首个元素,由于set容器插入时已经升序排序好了,此时删除的是最小的元素
printSet(s);
s.erase(10); //删除为10的元素
printSet(s);
//清空
s.clear(); //等价于s.erase(s.begin(),s.end());
printSet(s);
}
测试结果:
4.set的查找和统计
函数原型:
find(elem);
//查找容器中elem的位置,如果elem存在返回该元素的迭代器,不存在返回set.end();
count(elem);
//统计的容器中元素elem的个数,set容器元素个数只能是0或1,multiset容器可能大于1
测试案例:
void text()
{
set<int> s;
s.insert(5);
s.insert(3);
s.insert(4);
s.insert(2);
printSet(s);
//find()
set<int>::iterator pos = s.find(5);
if (pos != s.end())
{
cout << "找到元素:" << *pos << endl;
}
else cout << "没有该元素" << endl;
//count()
cout << "元素5" << "有" << s.count(5) << "个" << endl;
}
测试结果:
5.set和multiset的区别
区别:
- set不允许插入相同的数据,而multiset允许
- set插入数据的同时会返回插入结果,表示插入是否成功,该结果是用对组pair接收的
- multiset不会检测数据,因此可以插入相同数据
对组pair下面会详细介绍,现在先使用一下
测试案例:
void text()
{
set<int> s;
//用pair接收s的插入结果
pair < set<int>::iterator, bool > ret = s.insert(10);
if (ret.second)//ret的第二个类型数据,即bool类型,若为真则插入成功
{
cout << "插入成功" << endl;
}
else cout << "插入失败" << endl;
ret = s.insert(10);
if (ret.second)//ret的第二个类型数据,即bool类型,若为真则插入成功
{
cout << "插入成功" << endl;
}
else cout << "插入失败" << endl;
//multiset可以重复插入相同元素,不检测插入结果
multiset<int> ms;
ms.insert(10);
ms.insert(10);
ms.insert(10);
cout << "打印multiset容器:";
for (multiset<int>::iterator it = ms.begin(); it != ms.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
测试结果:
6.pair对组的创建
对组的概念:成对出现的数据
两种创建方式:
pair<T1,T2> p(value1,value2);
pair<T1,T2> p = make_pair(value1,value2);
使用:
p.first;
//返回对组的第一个类型的数据
p.second;
//返回对组的第二个类型的数据
值得一提的是使用pair并不需要头文件
测试案例:
void text()
{
//创建
pair<string, int> p1("张三", 25);
pair<string, int> p2 = make_pair("李四", 30);
//使用
cout << "姓名:" << p1.first << " 年龄:" << p1.second << endl;
cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;
}
测试结果:
7.set容器的排序规则
我们已经知道,在我们插入数据时,set容器会自动给我们排序好,默认情况是由小到大,也就是升序排序。
你应该会有疑惑了:
- 能不能改变排序规则,让其降序序排序
- 定义一个类,它有多个成员变量,那我们到底按照那个成员来排序呢
对于以上两种情况我们通常引入仿函数,自定义一个排序规则,如何排序由我们自己决定
测试案例:对内置数据类型排序
class Mycompare
{
public:
bool operator()(int v1,int v2) const //重载() 运算符
{
return v1 > v2; //指定排序规则,从大到小,也就是降序排序
}
};
void text1()
{
set<int,Mycompare> s1;
s1.insert(10);
s1.insert(50);
s1.insert(30);
s1.insert(40);
cout << "打印降序排序的set容器:" << endl;
for (set<int, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
测试结果:
测试案例:对自定义数据类型排序
class Person
{
public:
string m_name;
int m_age;
Person(string name, int age) :m_name(name), m_age(age) { }
};
class Mycompare
{
public:
bool operator()(const Person& p1,const Person& p2) const //重载() 运算符
{
return p1.m_age > p2.m_age;
}
};
void text1()
{
set<Person,Mycompare> s1;
Person p1("张三", 25);
Person p2("李四", 20);
Person p3("王五", 30);
s1.insert(p1);
s1.insert(p2);
s1.insert(p3);
cout << "按照年龄大小降序排序:" << endl;
for (set<Person, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
{
cout << "姓名:" << (*it).m_name << " 年龄:" << (*it).m_age << endl;
}
}
测试结果:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)