set是C++中的一种关联容器,具有以下特点:

  • 存储唯一元素(不允许重复)

  • 元素自动排序(默认升序)

  • 基于红黑树实现(平衡二叉搜索树)

  • 插入、删除和查找的时间复杂度为O(log n)


前言

在C++标准模板库(STL)中,setpair是两个非常重要且常用的组件。set是一种关联式容器,提供高效的查找、插入和删除操作;pair则是将两个值组合成一个单元的实用工具。本文将深入探讨它们的特性、用法以及实际应用场景。

1. pair 模板类详解

1.1 pair 的基本概念

pair 是 C++ 标准模板库中的一个实用模板类,定义在 <utility> 头文件中。它将两个值组合成一个单元,这两个值可以是相同或不同的类型。

#include <utility>  // 包含pair的定义
#include <iostream>
using namespace std;int main() {// 创建pair的三种方式pair<int, string> p1(1, "Apple");  // 直接构造auto p2 = make_pair(2, "Banana");  // 使用make_pair函数pair<int, string> p3 = {3, "Orange"};  // C++11统一初始化// 访问pair的成员cout << "p1: " << p1.first << ", " << p1.second << endl;cout << "p2: " << p2.first << ", " << p2.second << endl;cout << "p3: " << p3.first << ", " << p3.second << endl;return 0;
}

pair<T1, T2> 模板接受两个类型参数     first 和 second 是pair的两个公有成员,用于访问存储的值       make_pair 可以自动推导类型,比直接构造更简洁

1.2 pair 的比较操作

pair支持比较运算符,按照字典序进行比较:先比较first,如果first相等再比较second。

pair<int, int> a(1, 2);
pair<int, int> b(1, 3);
pair<int, int> c(2, 1);cout << boolalpha;
cout << (a < b) << endl;  // true (1==1, 2<3)
cout << (a < c) << endl;  // true (1<2)
cout << (b < c) << endl;  // true (1<2)

2. set 容器详解

set 的构造和初始化

#include <iostream>
#include <set>
using namespace std;int main() {// 空setset<int> s1;// 初始化列表(C++11)set<int> s2 = {3, 1, 4, 1, 5};  // 实际存储1,3,4,5// 使用数组范围初始化int arr[] = {2, 4, 6, 4, 2};set<int> s3(arr, arr + 5);  // 存储2,4,6// 拷贝构造set<int> s4(s3);// 输出set内容cout << "s2: ";for(int num : s2) cout << num << " ";cout << "\ns3: ";for(int num : s3) cout << num << " ";return 0;
}

set 会自动去重和排序     可以使用数组指针作为迭代器范围初始化    基于范围的for循环可以方便地遍历set

set 的常用操作

插入元素

set<string> fruits;
fruits.insert("Apple");
fruits.insert("Banana");
fruits.insert("Orange");// 检查插入是否成功
auto ret = fruits.insert("Apple");  // 尝试重复插入
if(!ret.second) {cout << "Apple already exists in set" << endl;
}

删除元素

// 通过值删除
fruits.erase("Banana");// 通过迭代器删除
auto it = fruits.find("Orange");
if(it != fruits.end()) {fruits.erase(it);
}// 删除范围
set<int> nums = {1, 2, 3, 4, 5};
nums.erase(nums.find(2), nums.find(4));  // 删除[2,4)

查找元素

set<int> s = {10, 20, 30, 40, 50};// 使用find()
auto it = s.find(30);
if(it != s.end()) {cout << "Found: " << *it << endl;
}// 使用count()
if(s.count(25) > 0) {cout << "25 exists" << endl;
} else {cout << "25 doesn't exist" << endl;
}

如果找到元素:返回指向该元素的迭代器   如果找不到元素:返回 s.end(),即指向 set 末尾的迭代器(不指向任何有效元素)。

set 与 pair 的结合使用

// 使用pair作为set的元素
set<pair<int, string>> studentScores;
studentScores.insert({90, "Alice"});
studentScores.insert({85, "Bob"});
studentScores.insert({95, "Charlie"});// 遍历
for(const auto& entry : studentScores) {cout << entry.second << ": " << entry.first << endl;
}/*
输出:
Bob: 85
Alice: 90
Charlie: 95
*/

性能对比

操作时间复杂度说明
insert()O(log n)插入元素并保持有序
erase()O(log n)删除元素
find()O(log n)查找元素
count()O(log n)检查元素是否存在
size()O(1)获取元素数量
empty()O(1)检查是否为空

pairset 和 map 的联系与区别

特性std::pairstd::setstd::map
元素类型任意两种类型的组合单一类型pair<const Key, Value>
元素数量固定两个成员(first和second)动态变化动态变化
排序方式无排序按元素值排序按键排序
唯一性不适用元素值唯一键唯一
访问方式直接访问.first和.second通过迭代器通过键或迭代器
查找效率不适用O(log n)O(log n)
插入操作直接构造insert()/emplace()insert()/emplace()/operator[]
典型应用场景多返回值、map元素需要唯一且有序的集合键值对关联存储
内存结构连续存储两个成员树状结构树状结构
修改限制两个成员都可修改元素不可修改(只能删除后插入)键不可修改,值可修改

std::set 的 "元素值唯一"

含义set 中存储的每个元素值都必须是唯一的,不能有重复。

std::set<int> numbers = {1, 2, 2, 3}; // 实际存储:{1, 2, 3}

​​​​​​底层机制set 在插入新元素时,会检查是否已存在相同的值。如果存在,则不会插入。

std::map 的 "键唯一"

含义map 中每个元素的键(key)必须是唯一的,但值(value)可以重复

std::map<std::string, int> ages = {{"Alice", 25},{"Bob", 25},    // 值可以重复{"Alice", 30}   // 键重复!第二个 "Alice" 会覆盖第一个
};

两个键 "Alice" 冲突时,后者会覆盖前者的值(最终 "Alice" 对应 30)。值 25 可以重复出现(如 "Alice" 和 "Bob" 的值都是 25


总结

pair 和 set 是C++ STL中非常重要的两个组件:

pair 用于将两个值组合成一个单元   set 用于维护一个唯一、有序的集合

它们可以单独使用,也可以结合使用(例如 set<pair<T1, T2>>)。理解它们的特性和正确使用方式,可以大大提高C++编程的效率和质量。

 

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

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

相关文章

终端命令行执行具体的方法名测试用例

你可以使用如下命令单独执行 test_mutation_login_by_email 方法:python3 manage.py test apps.login.test_client.LoginTestCase.test_mutation_login_by_email 注意事项: 路径 apps.login.test_client 要与你项目实际的 Python 包路径一致(即 test_client.py 文件所在的包…

20250620在Ubuntu20.04.6下编译KickPi的K7的Android14系统

【处理SDK】 rootrootrootroot-X99-Turbo:~/Android14$ tar zxvf rk3576-android14.0-20250217.tar.gz rootrootrootroot-X99-Turbo:~/Android14$ ll rootrootrootroot-X99-Turbo:~/Android14$ rm rk3576-android14.0-20250217.tar.gz rootrootrootroot-X99-Turbo:~/Android1…

碳中和时代的家电革命,从华为智选IAM看科技企业的环保担当

在"双碳"战略与品质消费浪潮的双重加持下&#xff0c;家电产业正经历一场前所未有的绿色革命。华为智选与空净十大品牌IAM的深度协同&#xff0c;不仅构建了智能家电领域的技术新高地&#xff0c;更通过系统性创新持续拓展着行业可持续发展的想象空间。从净水科技的突…

(C语言)Map数组的实现(数据结构)(链表)(指针)

源代码&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h>// 键值对节点 typedef struct Node {char* key;int value;struct Node* next; } Node;// Map结构 typedef struct {Node* buckets[100]; // 固定大小的哈希桶&#xff08;…

Logback示例解析

<configuration><!-- 环境变量 --><springProperty scope"context" name"app.name" source"spring.application.name" defaultValue"application"/><!-- 日志存放路径 --><property name"log.path&qu…

elementui响应式数据类型变更情况

背景。vue2。data中定义的响应数据类型是[]数组。应用在el-select中&#xff08;非multiple情况&#xff09;。当发生响应数据有变更渲染视图时&#xff0c;发现定义的数组转换成了字符串。 本身不是问题。但因为疏忽引发了watch监听formData数据时产生了产生了多次监听事件。…

人机融合智能 | 人智交互语境下的设计新模态

本章旨在探讨技术与设计领域在人智交互语境下的关系及其影响,讨论通过传统设计对人智交互的优化方法。通过回顾大数据和发展趋势,以 AI技术作为重要的技术推力,我们认为 AI技术将会在未来成为设计领域不可缺少的重要环节,并能够帮助设计师更加高效、准确地开展设计工作。本章着…

C++设计模式分类(GOF-23种设计模式)

文章目录 GOF-23 设计模式分类一、从目的分类1. 创建型&#xff08;Creational&#xff09;模式2. 结构型&#xff08;Structural&#xff09;模式3. 行为型&#xff08;Behavioral&#xff09;模式 二、从范围分类1. 类模式&#xff08;Class Pattern&#xff09;2. 对象模式&…

AbMole| LY294002(M1925)

LY294002是一种广谱的PI3K抑制剂&#xff0c;对PI3Kα/δ/β的IC50分别为0.5 μM/0.57 μM/0.97 μM。LY294002 也可以抑制 CK2 的活性&#xff0c;IC50 为 98 nM。LY294002 还是一种竞争性 DNA-PK 抑制剂&#xff0c;可逆结合 DNA-PK 的激酶结构域&#xff0c;IC50 为 1.4 μM…

第1章,[标签 Win32] :第一个 WIn32 程序,MessageBox 函数

专栏导航 上一篇&#xff1a;第1章&#xff0c;[标签 Win32] &#xff1a;第一个 WIn32 程序&#xff0c;程序入口 回到目录 下一篇&#xff1a;无 本节前言 本节的学习&#xff0c;需要前两节的内容作为先修知识。如果还没有去看本专栏的前两节&#xff0c;请你先去学习它…

求助帖:学Java开发方向还是网络安全方向前景好

最近网络安全被一个培训机构吹得天花乱坠&#xff0c;虽然他家既有网安又有java和UI&#xff0c;我也是学软件工程的&#xff08;山西某211&#xff0c;此机构是每年和我们学校合作的校企公司&#xff09;&#xff0c;但那里的老师仍然大力推荐我学网络安全&#xff08;渗透、代…

OpenCV 图像仿射变换之旋转

一、知识点 1、void warpAffine(InputArray src, OutputArray dst, InputArray M, Size dsize, int flags INTER_LINEAR, int borderMode BORDER_CONSTANT, …

HCIP-数据通信基础

前言&#xff1a;本博客仅作记录学习使用&#xff0c;部分图片出自网络&#xff0c;如有侵犯您的权益&#xff0c;请联系删除 本篇笔记是根据B站上的视频教程整理而成&#xff0c;感谢UP主的精彩讲解&#xff01;如果需要了解更多细节&#xff0c;可以参考以下视频&#xff1a;…

C语言基本数据类型与变量详解

# C语言基本数据类型与变量详解 ## 数据类型概述 在C语言中&#xff0c;数据类型决定了变量在内存中的存储方式和大小&#xff0c;以及可以对其执行的操作。合理选择数据类型能够提高程序的效率和准确性&#xff0c;避免内存浪费和数据溢出等问题。 C语言的基本数据类型主要包括…

Babylon.js学习之路《十、高级几何体:自定义模型与复杂形状生成》

文章目录 1. 引言&#xff1a;高级几何体的应用场景2. 参数化建模&#xff1a;Babylon.MeshBuilder2.1 扩展几何体类型2.2 自定义多边形&#xff08;ExtrudePolygon&#xff09; 3. 顶点级建模&#xff1a;自定义VertexData3.1 手动定义顶点数据3.2 动态生成地形&#xff08;高…

【赵渝强老师】Kubernetes的安全框架

Kubernetes集群的安全框架主要由以下认证、鉴权和准入控制三个阶段组成。这三个阶段的关系如下图所示。 视频讲解如下 【赵渝强老师】Kubernetes的安全框架 认证&#xff08;Authentication&#xff09; 当客户端与Kubernetes集群建立HTTP通信时&#xff0c;首先HTTP请求会进…

CDN与静态资源优化

CDN与静态资源优化 在现代Web系统和AI应用中&#xff0c;随着用户访问量的不断攀升&#xff0c;静态资源&#xff08;如HTML、CSS、JavaScript、图片、音视频、模型文件等&#xff09;带来的负载日益沉重。尤其在大模型推理、前端渲染、广告投放等场景中&#xff0c;静态资源的…

如何填写“appium inspector”内容?

1. 确认已经开启appium的服务&#xff0c;运行appium 参考内容&#xff1a;{"appium:platformName": "Android", # 系统名称"appium:platformVersion": "9", # 安卓版本&#xff0c;看设备"appium:deviceName": "3d…

mysql server层做了什么

服务器处理客户端请求 服务器程序在处理来自客户端的查询请求时&#xff0c;大致需要分为3部分&#xff1a;连接管理、解析与优化、存储引擎。 连接管理 每当有一个客户端进程连接到服务器进程时&#xff0c;服务器进程都会创建一个线程专门处理与这个客户端的交互&#xff…

APISIX 简介:云原生 API 网关的架构与实践

文章目录 引言&#xff1a;APISIX 概述基于Nginx构建的原因基于etcd构建的原因 架构图示架构分层解析管理层&#xff1a;人机交互与配置入口控制层&#xff1a;配置管理与集群协调数据面&#xff1a;请求处理与流量转发说明&#xff1a;关于OpenRestry 引言&#xff1a;APISIX …