【C++】提高编程——03STL常用容器——set/multset容器

8 set/multiset 容器

8.1 set 基本概念

  简介:所有元素都会在插入时自动排序
  本质:set/multiset属于关联式容器,底层结构是用二叉树实现
  set和multiset区别:
  (1)set不允许容器中有重复元素
   (2)multiset允许容器中有重复元素

8.2 set构造和赋值

   功能描述:set容器创建及赋值
   函数原型:
   (1)构造函数
   1.set < T > st;——默认构造函数
   2.set(const set &st);——拷贝构造函数
   (2)赋值操作
   set &operator=(const set &st);——重载=操作符

#include<iostream>
using namespace std;
//包含容器头文件
#include <set>

void printSet(set<int> &s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	//1.默认构造函数:set<int> s;
	set<int> s;
	
	s.insert(2);//插入数据只有insert方式
	s.insert(5);
	s.insert(4);
	s.insert(2);
	printSet(s);//打印set中的数据:输出2/4/5
	//2.拷贝构造
	set<int>s2(s);
	printSet(s2);

	//3.赋值操作
	set<int>s3 = s;
	printSet(s3);

}
int main()
{
	test01();
}

8.3 set 大小和交换

   功能描述:统计set容器大小以及交换set容器
   函数原型:
   (1)s.size();——返回容器中元素的个数
   (2)s.empty();——判断容器是否为空
   (3)s1.swap(s2);——交换两个集合容器

#include<iostream>
using namespace std;


//包含容器头文件
#include <set>

void printSet(set<int>& s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	set<int> s;
	s.insert(2);
	s.insert(5);
	s.insert(4);
	s.insert(2);
	printSet(s);

	//1.set容器中元素个数s.size()
	cout << "set容器中元素个数:" << s.size() << endl;

	//2.判断容器是否为空:s.empty()
	cout << "set容器中是否为空!" << s.empty() << endl;

	//3.交换两个容器s1.swap(s2)
	set<int>s3;
	s3.insert(6);
	s3.insert(4);
	s3.insert(6);
	cout << "交换前——————————————————" << endl;
	printSet(s);
	printSet(s3);
	cout << "交换后——————————————————" << endl;
	s.swap(s3);
	printSet(s);
	printSet(s3);

}
int main()
{
	test01();
}

8.4 set插入和删除

   功能描述:set容器中进行
   (1)插入(s.insert())
   (2)删除(s.erase())

   函数原型:
   (1)s.insert(elem);——在容器中插入数据elem
   (2)s.clear();——清空容器中所有数据
   (3)s.erase(pos);——删除pos迭代器所指元素,返回下一个元素的迭代器
   (4)s.erase(beg,end);——删除区间[beg,end)的所有元素,返回下一个元素的迭代器
   (5)s.erase(elem);——删除容器中值为elem的元素

#include<iostream>
using namespace std;
//包含容器头文件
#include <set>

void printSet(set<int>& s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	set<int> s;
	//1.插入数据:s.insert(elem)
	s.insert(2);
	s.insert(5);
	s.insert(4);
	s.insert(2);
	printSet(s);
	//2.删除pos位置的元素:s.erase(pos)
	s.erase(s.begin());
	printSet(s);
	//3.删除指定元素elem:s.erase(elem)
	s.erase(5);
	printSet(s);
	//4.删除指定区间[beg,end)之间的元素:s.erase(beg,end)
	s.erase(s.begin(), s.end());
	printSet(s);
	//5.清空set容器:s.clear()
	set<int> s1;
	s1.insert(2);
	s1.insert(5);
	s1.insert(4);
	printSet(s1);
	s1.clear();
	printSet(s1);
}
int main()
{
	test01();
}

8.5 set查找和统计

   功能描述:set容器中进行
   (1)查找(s.find(key))
   (2)删除(s.count(key))

   函数原型:
   (1)s.find(key);——查找key是否存在,若存在,返回该键元素的迭代器,若不存在,返回set.end()
   (2)s.count();——统计key的元素个数

#include<iostream>
using namespace std;


//包含容器头文件
#include <set>

void printSet(set<int>& s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	set<int> s;
	s.insert(2);
	s.insert(5);
	s.insert(4);
	s.insert(2);
	printSet(s);

	//1.查找key是否存在,若存在,返回该键元素的迭代器,若不存在,返回set.end():s.find(key)
	set<int>::const_iterator it = s.find(4);//返回迭代器
	if (it != s.end())
	{
		cout << "找到元素,值为:" << *it << endl;
	}
	else
	{
		cout << "未找到元素" << endl;
	}

	//2.统计key的元素个数:s.count()
	int num = s.count(4);
	cout << "set容器中4的个数为:" << num << endl;
}
int main()
{
	test01();
}

8.6 set和multiset的区别

   区别:
   (1)set不可以插入重复数据,multiset可以插入重复数据
   (2)set插入数据的同时会返回插入结果,标书插入是否成功
   (3)multiset不会检测数据,因此可以插入重复数据

#include<iostream>
using namespace std;

//包含容器头文件
#include <set>

void printSet(set<int>& s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void printMultiset(multiset<int>& ms)
{
	for (multiset<int>::const_iterator it = ms.begin(); it != ms.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}
void test01()
{
	//(1)set容器不允许插入重复数据:set.inset()返回对组数据类型pair<set<int>::const_iterator,bool>
	set<int> s;
	pair<set<int>::const_iterator,bool> ret=s.insert(2);
	if (ret.second)
	{
		cout << "第一次插入2成功!" << endl;
	}
	else
	{
		cout << "第一次插入2失败!" << endl;
	}
	s.insert(5);
	pair<set<int>::const_iterator, bool> ret2=s.insert(2);
	if (ret2.second)
	{
		cout << "第二次插入2成功!" << endl;
	}
	else
	{
		cout << "第二次插入2失败!" << endl;
	}
	printSet(s);

	//(2)multiset容器允许插入重复数据

	multiset<int> ms;
	ms.insert(2);
	ms.insert(5);
	ms.insert(2);
	printMultiset(ms);
}
int main()
{
	test01();
}

8.7 set容器排序

   学习目标:
   set容器默认排序规则为从小到大
   主要技术点:
   利用仿函数,可以改变排序规则

#include<iostream>
using namespace std;
#include<string>
//包含容器头文件
#include <set>

void printSet(set<int>& s)
{
	for (set<int>::const_iterator it = s.begin(); it != s.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;
}

//(1)内置数据类型排序
class MyCompare
{
public:
	//重载()
	bool operator()(int &v1,int &v2)
	{
		return v1 > v2;
	}
};
void test01()
{
	cout << "内置数据类型排序——————————" << endl;
	//默认排序:升序
	set<int> s1;
	s1.insert(12);
	s1.insert(10);
	s1.insert(2);
	s1.insert(11);
	s1.insert(13);
	s1.insert(21);
	for (set<int>::iterator it = s1.begin(); it != s1.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	

}
//(2)自定义数据类型排序

class Person
{
public:
	Person(string name,int age)
	{
		this->m_Age = age;
		this->m_Name = name;
	}
	string m_Name;
	int m_Age;
};
class comparePerson
{
public:
	bool operator()(const Person& p1, const Person& p2)
	{
		//按照年龄进行排序
		return p1.m_Age > p2.m_Age;
	}
};
void test02()
{
	cout << "自定义数据类型排序——————————" << endl;
	//1.创建容器,并向容器中插入数据
	set<Person, comparePerson> s;//自定义数据类型需要指定排序规则,否者不知道按照什么顺序插入
	Person p1("刘备", 24);
	Person p2("关羽", 21);
	Person p3("张飞", 18);
	Person p4("赵云", 22);
	s.insert(p1);
	s.insert(p2);
	s.insert(p3);
	s.insert(p4);


	//2.遍历容器中的数据
	for (set<Person,comparePerson>::iterator it = s.begin(); it != s.end(); it++)
	{
		cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << endl;
	}
	//3.
}
int main()
{
	test01();
	test02();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值