set容器的使用——C++

一、set容器

一、set容器的基本概念

  • 所有元素都会在插入set容器时自动排序
  • set/multiset属于关联式容器,底层结构是二叉树
  • set容器不允许存在重复元素
  • multiset允许存在重复元素

二、set容器的构造与赋值

#include<iostream>
#include<set>
using namespace std;
void printSet(set<int>&s)
{
	for (set<int>::iterator it = s.begin(); it != s.end(); it++)
		cout << *it << " ";
	cout << endl;
}
void test01()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	printSet(s1);
	set<int>s2(s1);
	printSet(s2);
	set<int>s3;
	s3 = s2;
	printSet(s3);
}

自行设置一个打印函数。set容器用insert插入数据,无需指定位置,按照自身顺序插入数据。拷贝构造和=号赋值可以使用。

三、set容器的大小与交换

void test02()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	printSet(s1);
	if (s1.empty())
		cout << "s1为空" << endl;
	else
		cout << "s1不为空,元素个数为:" <<s1.size()<< endl;
	set<int>s2;
	s2.insert(1);
	s2.insert(3);
	s2.insert(5);
	s2.insert(7);
	cout << "交换前" << endl;
	printSet(s1);
	printSet(s2);
	cout << "交换后" << endl;
	s1.swap(s2);
	printSet(s1);
	printSet(s2);
}

这些容器基本都是这么几个函数,知道怎么用就行

四、set容器的插入与删除

void test03()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	printSet(s1); 
	s1.erase(s1.begin());
	printSet(s1);
	s1.erase(30);
	printSet(s1);
	s1.clear();
	printSet(s1);
}

这里的erase有传值删除的重载版本

五、set容器的查找与统计

void test04()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(20);
	s1.insert(30);
	s1.insert(40);
	//无效
	s1.insert(30);
	s1.insert(30);
	auto pos=s1.find(30);
	if (pos != s1.end())
		cout << "找到了" << *pos << endl;
	else
		cout << "没找到" << endl;
	int num = s1.count(30);
	cout << "num=" << num << endl;
}

find的返回值类型是迭代器类型
set容器不允许有重复数据,因此count计数的结果要么是0,要么是一

六、set和multiset的区别

void test05()
{
	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;
	multiset<int>ms;
	ms.insert(10);
	ms.insert(10);
	ms.insert(10);
	for (auto it : ms)
		cout << it << " ";
	cout << endl;
}

在这里插入图片描述

二者最主要的区别在于是否能插入重复元素
multiset的使用无需引入新的头文件,上述案例中,pair是对组。下面会讲
模板中第一个类型是迭代器,第二个是bool类型,ret接收后,ret.second表示第二个参数返回值,及bool类型。可以看到set第二次插入重复数据就失败了,而multiset可以多次插入重复数据。

七、set容器排序

set容器默认从小到大排序,利用仿函数可以改变排序规则

class cmp
{
public:
	bool operator()(int v1, int v2)
	{
		return v1 > v2;
	}
};
void test06()
{
	set<int>s1;
	s1.insert(10);
	s1.insert(30);
	s1.insert(50);
	s1.insert(40);
	s1.insert(20);
	printSet(s1);
	set<int,cmp>s2;
	s2.insert(10);
	s2.insert(30);
	s2.insert(50);
	s2.insert(40);
	s2.insert(20);
	for (set<int, cmp>::iterator it = s2.begin(); it != s2.end(); it++)
		cout << *it << " ";
	cout << endl;
}

在这里插入图片描述
可以看到默认存储为升序,降序需要设置一个仿函数
对于自定义数据类型的存储必须设置仿函数,否则set不知道如何存储

#include<string>
class Person
{
public:
	Person(string name, int age)
	{
		this->m_age = age;
		this->m_name = name;
	}
	string m_name;
	int m_age;
};
class Compare
{
public:
	bool operator()(const Person&p1, const Person&p2)
	{
		return p1.m_age > p2.m_age;
	}
};
void test07()
{
	set<Person,Compare>s;
	Person p[5] = 
	{
	{"关羽",28},
	{"张飞",25},
	{"赵云",24},
	{"马超",23},
	{"黄忠",30}
	};
	for (int i = 0; i <5; i++)
		s.insert(p[i]);
	for (set<Person,Compare>::iterator it=s.begin();it!=s.end();it++)
		cout << "姓名:" << it->m_name << "年龄:" << it->m_age << endl;

}

在这里插入图片描述
这里需要注意,只要姓名和年龄有元素重复,set容器第二次存储都会失败,当作重复存储

二、对组pair

成对出现的数据,利用对组我们可以返回两个数据

#include<iostream>
#include<string>
using namespace std;
int main()
{
	pair<string, int>p("Tom", 20);
	cout << "姓名:" << p.first << " 年龄" << p.second << endl;
	pair<string, int>q("Jerry", 20);
	cout << "姓名:" << q.first << " 年龄" << q.second << endl;
	return 0;
}

像这样就可以存储多个数据,像简化的结构体,不过只能存两个,从名字对组也能看出

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

...404 Not Found

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

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

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

打赏作者

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

抵扣说明:

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

余额充值