• 【STL】set/multiset容器


    1. set容器基本概念

    简介:

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

    本质:

    • set/multiset属于关联式容器,底层结构是用二叉树实现的。

    set和multiset容器的区别:

    1. set不允许容器中有重复的元素
    2. multiset允许容器中有重复的元素

    2. set容器构造和赋值

    功能描述:

    • 创建set容器并赋值

    函数原型:

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

    示例:

    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(60);
    	s1.insert(40);
    	s1.insert(20);
    	printSet(s1);
    
    	//拷贝构造
    	set<int> s2(s1);
    	printSet(s2);
    
    	//赋值
    	set<int> s3;
    	s3 = s2;
    	printSet(s3);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    总结:

    1. set容器插入数据时用insert()
    2. set容器插入数据会自动排序

    3. set容器大小和交换

    功能描述:

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

    函数原型:

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

    示例:

    void test01()
    {
    	set<int> s1;
    	s1.insert(40);
    	s1.insert(20);
    	s1.insert(10);
    	s1.insert(30);
    
    	if (s1.empty())
    	{
    		cout << "s1为空" << endl;
    	}
    	else
    	{
    		cout << "s1不为空" << endl;
    		cout << "s1大小为:" << s1.size() << endl;
    	}
    
    	set<int> s2;
    	s2.insert(400);
    	s2.insert(200);
    	s2.insert(100);
    	s2.insert(300);
    	//交换
    	s2.swap(s1);
    	printSet(s1);
    	printSet(s2);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    总结:

    1. 统计大小——size()
    2. 判断是否为空——empty()
    3. 交换容器——swap()

    4. set容器插入和删除

    功能描述:

    • set容器进行插入数据和删除数据

    函数原型:

    insert(elem); //在容器中插入元素。
    clear(); //清除所有元素
    erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器。
    erase(beg, end); //删除区间[beg,end)的所有元素 ,返回下一个元素的迭代器。
    erase(elem); //删除容器中值为elem的元素。
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例:

    void test01()
    {
    	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();
    	s1.erase(s1.begin(), s1.end());
    	printSet(s1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    总结:

    1. 插入——insert()
    2. 删除——erase()
    3. 清空——clear()

    5. set容器查找和统计

    功能描述:

    • 对set容器进行查找数据和统计数据个数

    函数原型:

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

    示例:

    void test01()
    {
    	set<int> s1;
    	//插入
    	s1.insert(10);
    	s1.insert(20);
    	s1.insert(30);
    	s1.insert(40);
    	printSet(s1);
    
    	//查找
    	set<int>::iterator pos = s1.find(30);
    	if (pos != s1.end())//切记end表示最后一个元素的后一个位置
    	{
    		cout << "找到了该元素:" << *pos << endl;
    	}
    	else
    	{
    		cout << "未找到该元素" << endl;
    	}
    
    	//统计
    	int num = s1.count(30);
    	cout << "num = " << num << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    总结:

    1. 查找——find()(返回的是迭代器)
    2. 统计——count()(对于set容器,结果为0或1)

    6. set和multiset容器的区别

    区别:

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

    示例:

    void test01()
    {
    	set<int> s;
    	pair<set<int>::iterator, bool> ret = s.insert(10);//pair对组
    	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);
    	for (multiset<int>::iterator it = ms.begin(); it != ms.end(); ++it)
    	{
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    总结:

    1. 如果不允许插入重复的数据可以利用set
    2. 如果需要插重复的数据需要利用multiset

    7. pair对组的创建

    功能描述:

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

    两种创建方式:

    pair<type, type> p ( value1, value2 );
    pair<type, type> p = make_pair( value1, value2 );
    
    • 1
    • 2

    示例:

    void test01()
    {
    	pair<string, int> p("Tom", 18);
    	cout << "姓名:" << p.first << " 年龄:" << p.second << endl;
    
    	pair<string, int> pp = make_pair("jimmy", 20);
    	cout << "姓名:" << pp.first << " 年龄:" << pp.second << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    8. set容器的排序

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

    set存放内置数据类型的排序

    示例:

    class MyCompare
    {
    public:
    	bool operator()(int val1, int val2)const
    	{
    		return val1 > val2;
    	}
    };
    
    void test01()
    {
    	set<int> s1;
    	s1.insert(10);
    	s1.insert(50);
    	s1.insert(20);
    	s1.insert(40);
    	s1.insert(30);
    	//默认从小到大的排序
    	printSet(s1);
    
    	//指定排序规则
    	set<int, MyCompare> s2;
    	s2.insert(10);
    	s2.insert(50);
    	s2.insert(20);
    	s2.insert(40);
    	s2.insert(30);
    	for (set<int, MyCompare>::iterator it = s2.begin(); it != s2.end(); it++)
    	{
    		cout << *it << " ";
    	}
    	cout << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    注意:要在仿函数的后面加上const,不然会报错

    set存放自定义数据类型的排序

    示例:

    class Person
    {
    public:
    	string m_name;
    	int m_age;
    public:
    	Person(string name, int age)
    	{
    		m_name = name;
    		m_age = 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("张三", 18);
    	Person p2("李四", 20);
    	Person p3("王五", 30);
    	Person p4("老六", 12);
    	Person p5("老八", 15);
    
    	s.insert(p1);
    	s.insert(p2);
    	s.insert(p3);
    	s.insert(p4);
    	s.insert(p5);
    
    	for (set<Person, comparePerson>:: iterator it = s.begin(); it != s.end(); ++it)
    	{
    		cout << "姓名:" << it->m_name << " 年龄:" << it->m_age << endl;
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    这里面,我们要记住,这里面的对象的年龄不可以有相同的,有相同的话,set容器会自动去掉。如果有相同年龄的我们可以使用multiset容器。

  • 相关阅读:
    Python 无废话-基础知识函数详解
    linux系统管理之磁盘分区及管理
    【opencv-c++】windows10系统VisualStudio2022配置opencv_contrib-4.6.0
    七夕,用HTML+CSS动画实现旋转图片表白魔方感动她
    面试题:你是如何计划和组织一个大型的软件测试项目的?
    Python 批量合并图片到word文档
    apolloconfig分布式部署
    设计模式-责任链模式(Chain of Responsibility)
    【Unity】苹果(IOS)开发证书保姆级申请教程
    01.shiro入门
  • 原文地址:https://blog.csdn.net/qq_59702185/article/details/126659953