C++进阶-STL set/multiset容器和map容器的简单认识

set/multiset容器的简单认识

    • set基本概念
      • set与multiset 的区别:
      • set容器的构造和赋值
      • set容器的大小和交换
      • set容器的插入与删除
      • set容器的查找和统计
      • set容器-set和multiset的区别
      • set容器内置类型指定排序规则
      • set容器自定义数据类型指定排序规则
    • pair对组创建
    • map容器的基本概念
      • map容器构造和赋值
      • map容器大小和交换
      • map容器插入和删除
      • map容器查找和统计
      • map容器排序

set基本概念

set的所有元素在插入时会自动被排序,其本质 set/multiset 属于并联式容器,底层结构是用二叉树实现的

set与multiset 的区别:

  • set不允许容器中有重复的元素
  • multiset允许容器中有重复的元素

使用时仅需要包含一个 set 的头文件

#include <set>

set容器的构造和赋值

  • set<T> st; 默认构造函数
#include <iostream>
#include <string>
#include <set>
using namespace std;int main()
{//默认构造函数set<int> st;st.insert(12);
}
  • set(const set<T>& st); 拷贝构造函数
#include <iostream>
#include <string>
#include <set>
using namespace std;int main()
{//默认构造函数set<int> st;st.insert(12);//拷贝构造函数set<int> st2(st);
}
  • set& operator=(const set<T>& st); 重载等号操作符
#include <iostream>
#include <string>
#include <set>
using namespace std;int main()
{//默认构造函数set<int> st;st.insert(12);set<int> st2;//重载等号操作符赋值st2 = st;
}

set容器的大小和交换

用于统计set容器的大小以及交换set容器

  • size(); 返回容器中元素的数目
在这里插入代码片
  • empty(); 判断容器是否为空
#include <iostream>
#include <string>
#include <set>
using namespace std;int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}string str = (((int)st.empty()) == 0) ? "不为空" : "为空";std::cout << "容器st是否为空: " << str << std::endl;
}

在这里插入图片描述

  • swap(st); 交换两个集合容器
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}set<int> st2;for (int i = 11; i < 20; i++){st2.insert(i);}std::cout << "执行交换前 st的数据信息为:" << std::endl;printf(st);std::cout << "执行交换前 st2的数据信息为:" << std::endl;printf(st2);st.swap(st2);std::cout << "执行交换后 st的数据信息为:" << std::endl;printf(st);std::cout << "执行交换后 st2的数据信息为:" << std::endl;printf(st2);
}

执行结果

set容器的插入与删除

  • insert(elem); 在容器中插入元素
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);for (int i =100; i > 90; i--){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);
}

运行结果
以上案例说明set容器在插入元素后,会进行排序

  • clear(); 清除所有元素
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);st.clear();std::cout << "清空数据据后 st的数据信息为:" << std::endl;printf(st);
}

执行结果

  • erase(pos); 删除pos迭代器所指的元素,返回下一个元素速度迭代器
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);set<int>::iterator it = st.erase(st.begin());std::cout << "删除st.begin元素后 返回的下一元素位置指向:" << *it << std::endl;std::cout << "删除st.begin元素后 set容器值列表为:" << std::endl;printf(st);
}

执行结果

  • erase(beg, end); 删除区间[beg, end)的所有元素,返回下一个元素的迭代器
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);set<int>::iterator it = st.erase(st.begin(), ++(++st.begin()));std::cout << "删除[st.begin, ++(++st.begin()))元素后 返回的下一元素位置指向:" << *it << std::endl;std::cout << "删除元素后 set容器值列表为:" << std::endl;printf(st);
}

执行结果

  • earse(elem); 删除容器中值为elem的元素
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);st.erase(1);std::cout << "删除元素 1 后 set容器值列表为:" << std::endl;printf(st);
}

执行结果

set容器的查找和统计

  • find(key); 查找key是否存在,若存在,返回该key值的元素的迭代器,若不存在,返回 set.end();
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const set<int> st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{set<int> st;for (int i = 0; i < 10; i++){st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);set<int>::iterator it = st.find(1);std::cout << "查找元素 1 的位置:" << &it << " 其指向的元素值为:"  << *it << std::endl;set<int>::iterator it_not_find = st.find(100);if (it_not_find == st.end()){std::cout << "元素100 未查找到" << std::endl;}
}

执行结果

  • count(key); 统计元素key的个数
#include <iostream>
#include <string>
#include <set>
using namespace std;void printf(const multiset<int> st)
{for (multiset<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}int main()
{multiset<int> st;for (int i = 0; i < 10; i++){st.insert(i);st.insert(i);st.insert(i);}std::cout << "插入数据后 st的数据信息为:" << std::endl;printf(st);int count = st.count(1);std::cout << "统计元素 1 的数量,元素共有:" << count << " 个:" << std::endl;
}

执行结果
这里使用multiset举例,因为set不会存储重复插入的元素,所有元素数量均为1个

set容器-set和multiset的区别

  • set不可以插入重复数据,而multiset可以插入重复数据
  • set插入数据的同时会返回插入结果,表示插入是否成功
  • multiset不会监测数据,因此可以插入重复数据
#include <iostream>
#include <string>
#include <set>
using namespace std;int main()
{set<int> st;pair<set<int>::iterator, bool> ret = st.insert(3);if (ret.second){std::cout << "插入成功" << std::endl;}else{std::cout << "插入失败" << std::endl;}ret = st.insert(3);if (ret.second){std::cout << "插入成功" << std::endl;}else{std::cout << "插入失败" << std::endl;}
}

执行结果
内部使用的 pair<set<int>::iterator, bool> 是一个键值对的结构,调用set.insert() 后,会触发重复值监测,如果检测到重复值,那么会导致返回插入失败的结果
multiset没有这个操作

set容器内置类型指定排序规则

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

#include <iostream>
#include <string>
#include <set>
#include <ctime>
using namespace std;class CustomCompare
{
public://数据可能被修改,所以需要使用const限定调用函数的set对象不被修改bool operator()(int v1, int v2) const{return v1 > v2;}
};void printf(const set<int>& st)
{for (set<int>::const_iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}void printf_custom(set<int, CustomCompare>& st)
{for (set<int, CustomCompare>::iterator it = st.begin(); it != st.end(); it++){std::cout << *it << " ";}std::cout << std::endl;
}void init(set<int>& st)
{//随机数种子srand((unsigned int)time(NULL));for (int i = 0; i < 10; i++){st.insert(rand() % 60 + 40);}
}int main()
{set<int> st;init(st);std::cout << "初始化set后的值(当前是默认升序排列):" << std::endl;printf(st);//指定排序规则为从大到小 - 需要在创建容器的时候指定set<int, CustomCompare> st2;st2.insert(12);st2.insert(14);st2.insert(54);st2.insert(34);st2.insert(76);std::cout << "初始化set后的值(当前是定义了自定义仿函数排序规则):" << std::endl;printf_custom(st2);
}

运行结果

set容器自定义数据类型指定排序规则

#include <iostream>
#include <string>
#include <set>
#include <ctime>
using namespace std;class Person
{
private:string m_Name;int m_Age;
public:Person(string name, int age){this->m_Name = name;this->m_Age = age;}void printf() const{std::cout << "姓名:" << this->m_Name << " 年龄:" << this->m_Age << std::endl;}int getAge(){return this->m_Age;}
};class PersonCompare
{
public:bool operator()(Person p1, Person p2) const{return p1.getAge() > p2.getAge();}
};void printf(const set<Person, PersonCompare>& st)
{for (set<Person, PersonCompare>::const_iterator it = st.begin(); it != st.end(); it++){it->printf();}
}int main()
{set<Person, PersonCompare> st;Person p1("张三",12);Person p2("李四", 54);Person p3("王二", 23);Person p4("麻子", 87);Person p5("刘武", 45);Person p6("无硫", 22);st.insert(p1);st.insert(p2);st.insert(p3);st.insert(p4);st.insert(p5);st.insert(p6);printf(st);
}

执行结果

pair对组创建

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

两种创建方式:

  • pair<type, type> p (value, value2);
  • pair<type, type> p = make_pair(value, value2);
#include <iostream>
#include <string>
using namespace std;int main()
{pair<string, int> p1("测试Pair", 111);std::cout << "插入的值为:(" << p1.first << ", " << p1.second << ")" << std::endl;p1 = make_pair("测试pair第二次", 121);std::cout << "插入的值为:(" << p1.first << ", " << p1.second << ")" << std::endl;
}

执行结果

map容器的基本概念

  • map中所有元素都是pair
  • pair中的第一个元素是key(键值),起到索引所用,第二个元素是value(实值)
  • 所有元素都会根据元素的键值自动排列

本质:

  • map/multimap 属于并联式容器,底层结构是用二叉树实现

优点:

  • 可以根据key值快速查找到value值

map和multimap 的区别:

  • map不允许容器中有重复的key值元素
  • multimap允许容器中有重复的key值元素

map容器构造和赋值

  • map<T1, T2> mp; 默认构造函数
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{//默认构造函数map<string, int> mp;
}
  • map(const map<T1, T2>& mp); 拷贝构造函数
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{//默认构造函数map<string, int> mp;//拷贝构造map<string, int> mp2(mp);
}
  • map& operator=(const map& map); 重载等号操作符
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{//默认构造函数map<string, int> mp;//重载=号赋值map<string, int> mp2 = mp;
}

map容器大小和交换

  • size(); 返回容器中的元素的数目
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{map<string, int> mp;std::cout << mp.size() << std::endl;
}
  • empty(); 判别容器中元素是否为空
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{map<string, int> mp;mp.insert(pair<string,int>("测试", 12));std::cout << mp.empty() << std::endl;
}
  • swap(st); 交换两个集合容器
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{map<string, int> mp;map<string, int> mp2;mp.swap(mp2);
}

map容器插入和删除

  • insert(elem); 在容器中插入元素
#include <iostream>
#include <string>
#include <map>
using namespace std;int main()
{map<string, int> mp;//第一种方法mp.insert(pair<string,int>("测试", 12));//第二种方法mp.insert(make_pair("测试2", 12));//第三种方法mp.insert(map<int, int>::value_type("测试3", 12))//第四种 不建议使用 没有这个key值调用时,会根据您的key值创建一个信息数据出来并填充默认值mp["测试5"] = 13for(map<string, int>::iterator it = mp.begin(); it != mp.end(); it++){std::cout << "(" << (*it).first << " ," << (*it).second << ")" << std::endl; }
}
  • clear(); 清除所有元素
map<string, int> mp;
mp.insert(pair<string,int>("测试", 12));
mp.clear();
  • erase(pos); 删除pos迭代器所指的元素,返回下一个元素的迭代器
map<string, int> mp;
mp.insert(pair<string,int>("测试", 12));
map<string, int>::iterator next = mp.erase(mp.begin());
  • erase(beg, end); 删除[beg, end)区间所有的元素,返回下一个元素的迭代器
map<string, int> mp;
mp.insert(pair<string,int>("测试", 12));
map<string, int>::iterator next = mp.erase(mp.begin(), mp.end());
  • erase(key); 删除容器中key值为key的元素
map<string, int> mp;
mp.insert(pair<string,int>("测试", 12));
mp.erase(12);

map容器查找和统计

  • find(key); 查找key是否存在,若存在,返回该键的元素的迭代器,若不存在,返回map.end();
map<string, int> mp;
mp.insert(pair<string, int>("测试", 12));
map<string, int>::iterator find_result = mp.find("测试");
if (find_result == mp.end())
{std::cout << "未查找" << std::endl;
}
else
{std::cout << "查找到结果" << std::endl;
}
  • count(key); 统计key元素个数
multimap <string, int> mp;
mp.insert(pair<string, int>("测试", 12));
mp.insert(pair<string, int>("测试", 13));
int count =  mp.count("测试");
std::cout << "查找到结果" <<  count << "个" << std::endl;

map容器排序

利用仿函数,改变排序规则

#include <iostream>
#include <string>
#include <map>
using namespace std;class Compare
{
public:bool operator()(string k1, string k2) const{return k1 > k2;}
};int main()
{multimap <string, int , Compare> mp;mp.insert(pair<string, int>("测试1", 12));mp.insert(pair<string, int>("测试2", 13));for (map<string, int>::iterator it = mp.begin(); it != mp.end(); it++){std::cout << "(" << (*it).first << ", " << (*it).second << ")" << std::endl;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/139485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【3年轻量】腾讯云2核2G4M和2核4G5M服务器配置优惠价格表

腾讯云轻量应用服务器特价是有新用户限制的&#xff0c;所以阿腾云建议大家选择3年期轻量应用服务器&#xff0c;一劳永逸&#xff0c;免去续费困扰。腾讯云轻量应用服务器3年可以选择2核2G4M和2核4G5M带宽&#xff0c;3年轻量2核2G4M服务器540元&#xff0c;2核4G5M轻量应用服…

openEuler 系统使用 Docker Compose 容器化部署 Redis Cluster 集群

openEuler 系统使用 Docker Compose 容器化部署 Redis Cluster 集群 Redis 的多种模式Redis-Alone 单机模式Redis 单机模式的优缺点 Redis 高可用集群模式Redis-Master/Slaver 主从模式Redis-Master/Slaver 哨兵模式哨兵模式监控的原理Redis 节点主客观下线标记Redis 节点主客观…

django建站过程(4)创建文档显示页面

django建站过程&#xff08;4&#xff09;创建文档显示页面 创建文档显示页面项目主文件夹schoolapps中的文件urls.py在APP“baseapps”中创建url.py文件编写视图模板继承bootstrap创建head.html创建doclist.html创建docdetail.html 使用 markdown 编辑器安装模块Model 模型的d…

Azure 机器学习 - 机器学习中的企业安全和治理

目录 限制对资源和操作的访问网络安全性和隔离数据加密数据渗透防护漏洞扫描审核和管理合规性 在本文中&#xff0c;你将了解可用于 Azure 机器学习的安全和治理功能。 如果管理员、DevOps 和 MLOps 想要创建符合公司策略的安全配置&#xff0c;那么这些功能对其十分有用。 通过…

Unity中全局光照GI的总结

文章目录 前言一、在编写Shader时&#xff0c;有一些隐蔽的Bug不会直接报错&#xff0c;我们需要编译一下让它显示出来&#xff0c;方便修改我们选择我们的Shader&#xff0c;点击编译并且展示编译后的Shader后的内容&#xff0c;隐蔽的Bug就会暴露出来了。 二、我们大概回顾一…

【Python大数据笔记_day06_Hive】

hive内外表操作 建表语法 create [external] table [if not exists] 表名(字段名 字段类型 , 字段名 字段类型 , ... ) [partitioned by (分区字段名 分区字段类型)] # 分区表固定格式 [clustered by (分桶字段名) into 桶个数 buckets] # 分桶表固定格式 注意: 可以排序[so…

红队系列-IOT安全深入浅出

红队专题 设备安全概述物联网设备层次模型设备通信模型 渗透测试信息收集工具 实战分析漏洞切入点D-link 850L 未授权访问 2017 认证绕过认证绕过 D-link DCS-2530Ltenda 系列 路由器 前台未授权RTSP 服务未授权 访问 弱口令命令注入思科 路由器 固件二进制 漏洞 IoT漏洞-D-Lin…

OpenCV C++ 图像处理实战 ——《多二维码识别》

OpenCV C++ 图像处理实战 ——《多二维码识别》 一、结果演示二、zxing库配置2.1下载编译三、多二维码识别3.1 Method one3.1.1 源码3.2 Method two3.2.1 源码四、源码测试图像下载总结一、结果演示 </

ES6学习

let和const命名 let基本用法-块级作用域 在es6中可以使用let声明变量&#xff0c;用法类似于var ⚠️ let声明的变量&#xff0c;只在let命令所在的代码块内有效 {let a 10;var b 20; } console.log(a); //a is not defined console.log(b); //20不存在变量提升 var命令…

如何提升管理组织能力?

组织能力能力属于管理能力中的一部分&#xff0c;所以也称之为管理组织能力&#xff0c;组织是将人和事物的组合&#xff0c;有效的梳理和导向结果的能力。每个人都有组织能力&#xff0c;只是能力和效率上存在较大的差异。 一人的组织能力从学生时代就能体现出来&#xff0c;…

Unbuntu安装、测试和卸载gcc11

GCC 可用于编译 C、C&#xff0c;本文介绍如何 Ubuntu 上安装 gcc11、测试和卸载它。 1. 在Ubuntu 上安装 gcc11 添加工具链存储库 sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test在 Ubuntu 上安装 gcc11 sudo apt install -y gcc-11验证 gcc11 版本 gcc-11 --v…

尼得科电机的强大性能,将列车门和屏蔽门的开合变得从容而安全

城市脉动&#xff0c;人流涌动。 无论城市轨道交通还是远途铁路运输&#xff0c; 尼得科电机的强大性能&#xff0c;将列车门和屏蔽门的开合变得从容而安全。 尼得科的电机方案&#xff0c;有助于列车门稳准开闭&#xff0c;保障乘客安全无忧。高效驱动&#xff0c;让乘客的行程…

Fabric: 使用InvokeChaincode实现跨通道数据访问

因为工作中遇到一些问题考虑使用Fabric的跨通道链码调用方法InvokeChaincode()来解决&#xff0c;这篇文章主要是记录以下在Fabric测试网络中InvokeChaincode()的使用过程及遇到的问题。 1 前期准备 1.1 认识InvokeChaincode InvokeChaincode的作用是调用指定的链码。而被调用…

Oracle(15)Managing Users

目录 一、基础知识 1、Users and Security 用户和安全 2、Database Schema 3、Checklist for Creating Users创建用户步骤 二、基础操作 1、创建一个用户 2、OS Authentication 操作系统身份验证 3、Dropping a User 删除用户 4、Getting User Information 获取用户信…

Leetcode100120. 找出强数对的最大异或值 I

Every day a Leetcode 题目来源&#xff1a;100120. 找出强数对的最大异或值 I 解法1&#xff1a;模拟 枚举 2 遍数组 nums 的元素&#xff0c;更新最大异或值。 代码&#xff1a; /** lc appleetcode.cn id100120 langcpp** [100120] 找出强数对的最大异或值 I*/// lc c…

Leetcode—765.情侣牵手【困难】

2023每日刷题&#xff08;二十七&#xff09; Leetcode—765.情侣牵手 并查集置换环思路 参考自ylb 实现代码 class Solution { public:int minSwapsCouples(vector<int>& row) {int n row.size();int len n / 2;vector<int> p(len);iota(p.begin(), p.…

C语言--从键盘输入当月利润I,求应发奖金总数。

题目描述&#xff1a; 企业发放的奖金根据利润提成。利润I低于或等于100000元的&#xff0c;奖金可提成10%; 利润高于100000 元&#xff0c;低于200000元(1000001000000时&#xff0c;超过1000000元的部分按 1%提成。从键盘输入当月利润I,求应发奖金总数。 int main() {int m…

前端面试题 计算机网络

文章目录 ios 7层协议tcp协议和udp协议的区别tcp协议如何确保数据的可靠http和tcp的关系url输入地址到呈现网页有哪些步骤post和get本质区别&#xff0c;什么时候会触发二次预检GET请求&#xff1a;POST请求&#xff1a;触发二次预检&#xff08;CORS中的预检请求&#xff09;&…

c++ 信奥编程 1135:配对碱基链

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int main(){char a[256];int len;int i;gets(a);lenstrlen(a);//计算字符串长度for(i0; i<len; i){ //输出配对碱基if(a[i]A) cout<<"T";if(a[i]T) cout<…

yolo系列报错(持续补充ing)

文章目录 export GIT_PYTHON_REFRESHquiet解决 没有pt权重文件解决 python文件路径报错解决 读取文件列名报错解决 导入不同文件夹出错解决 megengine没有安装解决然后你发现它竟然还没有用 export GIT_PYTHON_REFRESHquiet 设置环境变量 GIT_PYTHON_REFRESH &#xff0c;这个…