当前位置: 首页 > news >正文

c++set和pair的使用

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++编程的效率和质量。

 

相关文章:

  • 小白的进阶之路系列之十六----人工智能从初步到精通pytorch综合运用的讲解第九部分
  • docker mysql启动后时间慢8小时问题
  • 24. 开发者常用工具:抓包,弱网模拟,元素检查
  • Tkinter快速入门指南
  • DataWhale-零基础络网爬虫技术(二er数据的解析与提取)
  • 粗浅理解:为什么左旋右旋的组合反而收旋转矩阵影响
  • ajax中get和post的区别
  • 5.基于神经网络的时间序列预测
  • Git 命令全景图:从 clone 到 merge 的完整流程解析
  • 【时时三省】(C语言基础)善于利用指针
  • 统计一个区间内的素数并求和
  • 3D Gaussian Splatting算法安装与实测
  • android 渲染流水线中的两个重要阶段:swapBuffers 和 DrawFrames
  • 大模型Text2SQL之在CentOS上使用yum安装与使用MySQL
  • 【Golang学习】1-基于mysql增删改查
  • 工具:Autosar:DBC转ARXML
  • 《Go语言圣经》利用结构体和接口实现更优雅的Go错误处理
  • Linux之线程同步与互斥
  • Plotly图表全面使用指南 -- Displaying Figures in Python
  • .docx 和 .doc 都是 Word 文档格式的区别
  • 中学生制作网站怎么做/谷歌浏览器 免费下载
  • 委托网络公司做的网站侵权/优化大师班级优化大师
  • 网站建设发票的税点/网络推广免费平台
  • 轮播网站/石家庄网络推广
  • 做网站的需求清单/爱网站查询
  • 帮别人做网站赚钱6/网店营销策划方案范文