【C++提高编程】3.7 STL常用容器:set/multiset容器

1. string容器

本章内容请点击跳转

2. vector容器

本章内容请点击跳转

3. deque容器

本章内容请点击跳转

4. stack容器

本章内容请点击跳转

5. queue容器

本章内容请点击跳转

6. list容器

本章内容请点击跳转

7. set/multiset容器

7.1 set/multiset基本概念

所有元素都会在插入时自动被排序。set/multiset属于关联式容器,底层结构是用二叉树实现。

set和multiset区别:

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

都包含头文件set即可

7.2 set/multiset构造和赋值

功能描述:

  • 创建set容器以及赋值

函数原型:

  • set<T> st;//默认构造函数
  • set(const set &st);//拷贝构造函数
  • set& operator=(const set& lst);//赋值:重载等号操作符

set在插入数据时,没有posh的操作了,只能采用insert方法

set<int>s1;

//插入数据
s1.insert(10);
s1.insert(40);
s1.insert(30);
s1.insert(20);
s1.insert(30);

//遍历容器
printSet(s1);//10 20 30 40

//拷贝构造
set<int>s2(s1);

//赋值
set<int>s3;
s3 = s2;

set特点:所有元素插入时候(insert)自动被排序;且不允许插入重复值(set会自动删掉)

7.3 set/multiset大小和交换

功能描述:

  • 统计set容器的大小以及交换set容器

函数原型:

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

不允许指定大小,因为如果指定过长,都要用0来填充,那么set就有重复数据了,但这是不允许的。

7.4 set/multiset插入和删除

功能描述:

  • 对set容器进行插入、删除操作

函数原型:

  • insert(elem);//在容器中插入元素
  • clear();//清除容器中所有元素
  • erase(pos);//删除pos位置的数据,返回下一个元素的迭代器
  • erase(beg, end);//删除[beg, end)区间的元素,返回下一个元素的迭代器
  • erase(elem);//删除容器中值为elem的元素
set<int>s1;

//插入数据
s1.insert(30);
s1.insert(20);
s1.insert(40);
s1.insert(10);

//遍历
printSet(s1);//10 20 30 40

//删除
s1.erase(s1.begin());
printSet(s1);//20 30 40
//删除的是10,不是30!!!!

//删除重载版本
s1.erase(30);
printSet(s1);//20 40

7.5 set/multiset查找和统计

功能描述:

  • 对set容器进行查找数据以及统计数据

函数原型:

  • find(key);//在查找key是否存在,若存在,返回该键的元素的迭代器;若不存在,返回set.end()
  • count(key);//统计key的元素个数
//查找
set<int>::iterator pos = s1.find(30);//用迭代器去接收
if (pos != s1.end())
{
	cout << "找到元素:" << *pos << endl;
}
else
{
	cout << "未找到元素" << endl;
}

//统计
int num = s1.count(30);
cout << "num = " << num << endl;

对于set而言,查找返回的结果是迭代器;统计的结果要么是0,要么是1(因为set不允许重复)

7.6 set和multiset区别

  • set不可以插入重复数据,而multiset可以
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会检测数据,因此可以插入重复数据

set不允许插入重复数据的原因在于,其实set返回的是一个pair(迭代器, bool)。如果重复,那么bool值为false,将不会插入成功,如下:

set<int>s;
pair<set<int>::iterator, bool> ret = s.insert(10);

if (ret.second)//第一次插入成功
{
	cout << "第一次插入成功" << endl;
}
else
{
	cout << "第一次插入失败" << endl;
}

ret = s.insert(10);
if (ret.second)//第二次插入失败
{
	cout << "第二次插入成功" << endl;
}
else
{
	cout << "第二次插入失败" << endl;
}

7.7 pair对组创建

功能描述:

  • 成对出现的数据,利用对组可以返回两个数据
  • 使用对组时,并不需要包含其它额外的头文件

函数原型:

  • pair<type, type> p (value, value2);
  • pair<type, type> p = make_pair(value, value2);
    调用:
  • p.first;//调用对组p的第一个参数值
  • p.second;//调用对组p的第二个参数值
pair<string, int>p("Tom", 20);
cout << "姓名:" << p.first << " 年龄:" << p.second << endl;

pair<string, int>p2 = make_pair("Jerry", 30);
cout << "姓名:" << p2.first << " 年龄:" << p2.second << endl;

7.8 set容器排序

功能描述:

  • set容器默认排序规则为从小到大,但排序规则可以改变

主要技术点:

  • 利用仿函数,可以改变排序规则

示例一:set存放内置数据类型

class Mycompare
{
public:
	bool operator()(int v1, int v2)const//小括号重载
	{
		return v1 > v2;
	}
};

void test01()
{
	set<int, Mycompare>s1;


	s1.insert(10);
	s1.insert(40);
	s1.insert(20);
	s1.insert(50);
	s1.insert(30);
	
	for (set<int, Mycompare>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;//50 40 30 20 10
}

需要自定义一个类,其中包含重载小括号的仿函数,并返回bool类型,输入的参数与set<int, Mycompare>s1;的第一个参数保持一致,set<>中的第二个参数为自定义的类名。

示例二:set存放自定义数据类型

class Person
{
public:
	Person(string name, int age)
	{
		this->m_Name = name;
		this->m_Age = age;
	}
	string m_Name;
	int m_Age;
};

class comparePerson
{
public:
	bool operator()(const Person&p1, const Person&p2)const//小括号重载
	{
		//按照年龄降序
		return p1.m_Age > p2.m_Age;
	}
};

void test01()
{
	//自定义数据类型都会指定排序规则
	set<Person, comparePerson>s;

	Person p1("Jenny", 24);
	Person p2("Bob", 28);
	Person p3("Anny", 25);
	Person p4("Sarah", 21);

	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);
	for (set<Person, comparePerson>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << "姓名:" << it->m_Name << " 年龄:" << it->m_Age << endl;
	}
}

【未完待续】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值