C++STL set/multiset容器的区别、pair对组创建、set容器排序、set排序 内置数据类型和自定义数据类型高级排序
创始人
2024-06-03 17:00:49
0

文章目录

  • 1 set和multiset区别
  • 2 pair对组创建
  • 3 set容器排序
    • 3.1 set存放内置数据类型
    • 3.2 set存放自定义数据类型

1 set和multiset区别

区别:

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

set.insert() set不能有重复值插入

在上一篇学习笔记知道set容器是不允许有重复值插入的,那么具体看看其中的原因。

首先,创建set容器,插入数据,选中insert→右键→转到定义,查看insert的定义
在这里插入图片描述
解释:
可以看到insert的返回值是pair类型,即返回值是对组类型,相当于返回值有两个数据,一个是迭代器iterator,表示插入值的位置,另一个是bool类型,表示这个值是否插入成功。对于set的insert而言,返回结果就是这个值是否插入成功,插入成功的话,也会有插入位置。其中,pair就是对组,是一组成对出现的数据。

multiset.insert() 允许有重复值插入
同样地,看看multiset容器中insert()函数是怎么定义的。
首先,创建set容器,插入数据,选中insert→右键→转到定义,查看insert的定义
在这里插入图片描述

解释:
在multiset容器中insert的返回值是一个迭代器,没有bool类型的返回值来判断是否重复插入,不像set容器中insert的返回值是pair对组类型。

接下来看看set容器和multiset容器重复插入一个值,insert的返回结果会有什么不一样。
测试代码:

void test1()
{int n = 30;cout << "set.insert() " << endl;set s1;//insert的返回值类型是pair对组类型(成对出现的数据,数据1是迭代器,数据2是bool类型)pair::iterator, bool> result1 = s1.insert(21);if (result1.second)//第二个数据是bool类型{cout << "第一次插入成功" << endl;//返回真 插入成功}else{cout << "第一次插入失败" << endl;}pair::iterator, bool> result2 = s1.insert(21);if (result2.second)//第二个数据是bool类型{cout << "第一次插入成功" << endl;//返回真 插入成功}else{cout << "第一次插入失败" << endl;}cout << string(n, '-') << endl;cout << "multiset.insert() " << endl;multiset s2;s2.insert(23);s2.insert(23);//insert的返回值类型是iterator类型 没有bool类型的返回值判断是否重复插入for (multiset::iterator it = s2.begin(); it != s2.end(); it++){cout << *it << "  ";}cout << endl;cout << string(n, '-') << endl;
}

在这里插入图片描述
解释:
可以看到在第二次插入值21时,insert第二个返回值是false,插入失败,无法插入重复值。也就是说insert第二个bool类型的返回值是用来检测重复值的,如果插入的是重复值,直接返回false;如果不是重复值,返回true。这很好地体现了set容器中为什么不能插入重复值。在set容器的定义中,如果有重复值插入,会直接返回一个插入失败结果

总结:

  • 如果不允许插入重复数据可以利用set
  • 如果需要插入重复数据利用multiset

2 pair对组创建

功能描述: 成对出现的数据,利用对组可以返回两个数据

两种创建方式:

  • pair p ( value1, value2 );
  • pair p = make_pair( value1, value2 );
    type是指数据类型

示例:

void test1()
{int n = 20;cout << "第一种方式" << endl;pair p1("Bella", 56);//类似默认构造 本质是类模板cout << "姓名:" << p1.first << "体重:" << p1.second << endl;//通过 . 访问第一个和第二个数据cout << string(n, '-') << endl;cout << "第二种方式" << endl;pair p2 = make_pair("Bella", 54);cout << "姓名:" << p2.first << "体重:" << p2.second << endl;
}

在这里插入图片描述

总结: 两种方式都可以创建对组,记住一种即可

3 set容器排序

学习目标: set容器默认排序规则为从小到大,掌握如何改变排序规则

主要技术点: 利用仿函数,可以改变排序规则

3.1 set存放内置数据类型

在之前的学习中,set插入数据时就会对数据进行一个排序,并且默认的排序规则是从小到大。那么如何改变这个排序规则呢?

class myCompare
{
public:bool operator()(int value1, int value2) const{return value1 > value2;}
};void test1()
{set s1;s1.insert(21);s1.insert(22);s1.insert(23);s1.insert(24);s1.insert(25);cout << "默认排序规则为从小到大  s1:";for (set::iterator it = s1.begin(); it != s1.end(); it++){cout << *it << "  ";}cout << endl;set s2;s2.insert(21);s2.insert(22);s2.insert(23);s2.insert(24);s2.insert(25);cout << "指定排序规则为从大到小  s2:";for (set::iterator it2 = s2.begin(); it2 != s2.end(); it2++){cout << *it2 << "  ";}cout << endl;

在这里插入图片描述

3.2 set存放自定义数据类型

class Person
{
public:Person(string name, int age, int height, int weight){this->m_name = name;this->m_age = age;this->m_height = height;this->m_weight = weight;}string m_name;int m_age;int m_height;int m_weight;
};class myCompare
{
public:bool operator()(const Person&p1, const Person&p2) const{if (p1.m_age == p2.m_age){return p1.m_height > p2.m_height;}else if (p1.m_height == p2.m_height){return p1.m_weight < p2.m_weight;}else{return p1.m_age > p2.m_age;}}
};void test1()
{//创建人物set s;string nameseed[] = { "张飞", "孙权", "西施", "貂蝉", "王昭君", "关羽" };int ageseed[] = { 28, 28, 25, 24, 26, 28 };int heightseed[] = { 178, 170, 153, 153, 153, 200 };int weightseed[] = { 140, 135, 108, 95, 100, 165 };for (int i = 0; i < 6; i++){Person p(nameseed[i], ageseed[i], heightseed[i], weightseed[i]);s.insert(p);}cout << "自定义数据类型 set" << endl;for (set::iterator it = s.begin(); it != s.end(); it++){cout << "姓名:" << it->m_name << "\t年龄:" << it->m_age<< "\t身高:" << it->m_height << "\t体重:" << it->m_weight << endl;}cout << endl;
}

在这里插入图片描述
注意点

  1. 在set还没有插入数据之前,就要指定set的排序规则,才会按照制定的排序规则插入数据;
  2. set的默认构造set st; ,参数类型是类模板,因此这个仿函数也封装在类中;
  3. 仿函数,即重载小括号,operator();
  4. 仿函数的返回值是bool类型;
  5. 仿函数的形参取决于容器插入的数据类型。如果set插入的数据是int, 那么仿函数的形参也应该是int类型,即bool operator()(int v1, int v2) { }。如果set插入的数据是自定义数据类型Person, 那么仿函数的形参也应该是Person类型,即bool operator()(const Person& v1, const Person& v2) { },这里加入const修饰,防止数据类修改;使用引用防止浅拷贝。
  6. 如果要访问这个容器的数据,迭代器的作用域也要相应地变化,set::iteratorset::iterator
  7. 在仿函数最后还要加上const修饰,否则会提示如下错误
    在这里插入图片描述

总结:

对于内置数据类型,利用仿函数可以指定set容器的排序规则即可;
对于自定义数据类型,set必须指定排序规则才可以插入数据。

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...