C++硬货——set头文件【保姆级教学】

355 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

set容器

set是C++标准库中的一种关联容器。所谓关联容器就是通过键(key)来读取和修改元素。与map关联容器不同,它只是单纯键的集合。

特点

所有元素都在插入时自动排序

本质

属于关联式容器,底层结构是排序二叉树实现

PS: 接下来会介绍set容器的(构造和赋值)、(大小和交换)、(插入和删除)、(查找和统计)、(更改set的排序规则),在相应的介绍下附有代码,代码中有文字介绍~

set的构造和赋值

构造:

  • set<T>s;//默认构造
  • set<T>s1(const set&s);//拷贝构造 赋值 s1=s;

代码

//set的构造和赋值
void test01() {
	//默认构造
	set<int>s1;
	//无序插入
	s1.insert(10);
	s1.insert(5);
	s1.insert(66);
	s1.insert(60);
	s1.insert(15);
	s1.insert(5);//重复插入5,这个5将不会插入
	display(s1);

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

	//赋值
	set<int>s3;
	s3 = s2;
	display(s3);
}

结果:

image.png

set大小和交换

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

代码

//set的大小和交换
void test02() {
	set<int>s1;
	//无序插入
	s1.insert(10);
	s1.insert(5);
	s1.insert(66);
	s1.insert(60);
	s1.insert(15);
	s1.insert(5);//重复插入5,这个5将不会插入
	display(s1);
	cout << "s1--size=" << s1.size() << endl;
	if (s1.empty()) {
		cout << "s1为空" << endl;
	}
	else {
		cout << "s1不为空" << endl;
	}

	set<int>s2;
	s2 = s1;
	//再插入三个数
	s2.insert(99);
	s2.insert(3);
	s2.insert(72);
	display(s2);

	//交换
	s2.swap(s1);
	cout << "s1:";
	display(s1);
	cout << "s2:";
	display(s2);
	//s1和s2交换成功
}

结果

image.png

set的插入和删除

插入

  • insert(elem);插入一个元素的同时排序
  • clear();清除set中所有的元素
  • erase(pos);删除pos迭代器所指的元素
  • erase(beg,end);删除【beg,end)的所有元素
  • erase(elem);删除set容器中值为elem的元素

代码

//set的插入和删除
void test03() {
	//插入就不多说了
	//默认构造
	set<int>s1;
	//无序插入
	s1.insert(10);
	s1.insert(5);
	s1.insert(66);
	s1.insert(60);
	s1.insert(15);
	s1.insert(5);//重复插入5,这个5将不会插入
	set<int>s2 = s1;
	display(s1);

	//删除
	s1.erase(s1.begin());
	display(s1);

	//clear
	s1.clear();
	display(s1);
	//或者s1.erase(s1.begin(),s1.end());

	//删除某个值
	s2.erase(66);
	display(s2);
}

结果

image.png

set的查找和统计

  • find(key);若key存在,返回该键的元素的迭代器,若不在,返回set.end();
  • count(key);统计key的元素个数(在set中要么是0要么是1)

代码

//set的查找和统计
void test04() {
	//默认构造
	set<int>s1;
	//无序插入
	s1.insert(10);
	s1.insert(5);
	s1.insert(66);
	s1.insert(60);
	s1.insert(15);
	s1.insert(5);//重复插入5,这个5将不会插入
	display(s1);

	//查找
	set<int>::iterator pos = s1.find(60);
	//如果没找到会到end迭代器
	if (pos != s1.end()) {
		cout << "查找成功!" << *pos << endl;
	}
	else {
		cout << "未找到该元素!" << endl;
	}

	//统计
	int cnt = s1.count(66);
	int cnt2 = s1.count(666);
	cout << "66的个数:" << cnt << endl;
	cout << "666的个数:" << cnt2 << endl;
	//在set容器中只有0或1
}

结果

image.png

set和multiset的区别

  • set中不允许插入重复的元素
  • multiset中允许插入重复的元素

代码

//set和multiset的区别
void test05() {
	//默认构造
	set<int>s1;
	//无序插入
	s1.insert(10);
	s1.insert(5);
	s1.insert(66);
	s1.insert(60);
	s1.insert(15);
	s1.insert(5);//重复插入5,这个5将不会插入
	cout << "s1遍历:" << endl;
	display(s1);

	//构造m
	multiset<int>m;
	m.insert(10);
	m.insert(5);
	m.insert(66);
	m.insert(60);
	m.insert(15);
	m.insert(5);//重复插入5,这个5将会插入
	cout << "m遍历:" << endl;
	for (multiset<int>::iterator it = m.begin(); it != m.end(); it++) {
		cout << *it << " ";
	}
}

结果

image.png

set排序规则更改

步骤:

1.创建一个仿函数bool operator()(int v1,int v2);
2.创建在该仿函数规则下的set容器

仿函数代码

class MyCompare {
public:
	bool operator()(int v1, int v2)const {
		return v1 > v2;
	}
};

测试代码

//set排序规则更改(仿函数)
void test06() {
	//默认构造
	set<int>s1;
	//无序插入
	s1.insert(10);
	s1.insert(5);
	s1.insert(66);
	s1.insert(60);
	s1.insert(15);
	s1.insert(5);//重复插入5,这个5将不会插入
	cout << "s1遍历:" << endl;
	display(s1);

	//指定排序规则为从大到小
	//默认构造
	set<int, MyCompare>s2;
	//无序插入
	s2.insert(10);
	s2.insert(5);
	s2.insert(66);
	s2.insert(60);
	s2.insert(15);
	s2.insert(5);//重复插入5,这个5将不会插入
	cout << "s2遍历:" << endl;
	for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++) {
		cout << *it << " ";
	}
	cout << endl;
}

结果

image.png PS: 看都看了,这不点赞收藏来一手~