C++ 新手指南:如何使用 set 和 unordered_set

news2024/11/7 13:18:22

在C++编程中,setunordered_set 是两个常用的容器,它们分别属于有序集合和无序集合。无论您是刚接触编程的小白,还是希望更深入了解C++ STL的使用者,理解它们的区别和使用场景,能够帮助您更高效地处理数据。

在本文中,我们将深入介绍这两个容器的使用方法、实现原理,并通过示例代码详细讲解如何应用它们。

setunordered_set 的区别

  1. 排序set 是有序的,即元素会按升序自动排列。unordered_set 是无序的,元素存储的顺序不固定。

  2. 底层实现set 使用红黑树(红黑树是一种平衡二叉树结构),unordered_set 使用哈希表。

  3. 时间复杂度:由于底层结构不同,二者的操作性能也有所差异。

    操作类型set 的时间复杂度unordered_set 的时间复杂度
    插入、删除O(log n)平均 O(1),最坏 O(n)
    查找O(log n)平均 O(1),最坏 O(n)

哈希(Hashing)是一种通过哈希函数将数据映射到固定大小的数组(称为哈希表)中的技术。哈希函数根据输入的元素值计算出一个哈希值,并根据哈希值将元素存储在哈希表的对应位置。哈希表的优势在于它能够在常数时间(O(1))内执行插入、查找和删除操作,特别适用于需要快速查找和去重的场景。对于 unordered_set 来说,它依赖哈希表来存储数据,因此可以在平均常数时间内完成元素的查找、插入和删除操作。

set 的使用方法

set 是一种自动排序的集合,它只存储唯一的元素。如果尝试插入重复的元素,set 会自动忽略。

代码示例

#include <iostream>
#include <set>

int main() {
    std::set<int> mySet;

    // 插入元素
    mySet.insert(10);
    mySet.insert(5);
    mySet.insert(15);
    mySet.insert(10);  // 重复元素,插入无效

    // 遍历元素
    std::cout << "Set 中的元素:";
    for (const auto &elem : mySet) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 查找元素
    int key = 10;
    if (mySet.find(key) != mySet.end()) {
        std::cout << key << " 存在于 set 中。" << std::endl;
    } else {
        std::cout << key << " 不存在于 set 中。" << std::endl;
    }

    return 0;
}

代码讲解

  • insert():用于将元素插入到set中,若元素已存在则不插入。
  • find():检查特定元素是否存在于集合中。
  • 迭代器遍历:for 循环通过 set 的迭代器实现遍历。

使用场景

当需要保持数据的有序性并确保唯一性时,set 是很好的选择。例如:处理排序后用户不重复的输入数据。

unordered_set 的使用方法

unordered_set 使用哈希表实现,因此插入和查找操作在平均情况下更高效,但数据存储顺序不固定。

代码示例

#include <iostream>
#include <unordered_set>

int main() {
    std::unordered_set<int> myUnorderedSet;

    // 插入元素
    myUnorderedSet.insert(10);
    myUnorderedSet.insert(5);
    myUnorderedSet.insert(15);
    myUnorderedSet.insert(10);  // 重复元素,插入无效

    // 遍历元素
    std::cout << "Unordered Set 中的元素:";
    for (const auto &elem : myUnorderedSet) {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 查找元素
    int key = 10;
    if (myUnorderedSet.find(key) != myUnorderedSet.end()) {
        std::cout << key << " 存在于 unordered_set 中。" << std::endl;
    } else {
        std::cout << key << " 不存在于 unordered_set 中。" << std::endl;
    }

    return 0;
}

代码讲解

  • insert():将元素插入 unordered_set,重复元素会被自动忽略。
  • find():查找某元素是否在集合中。
  • 由于元素无序,遍历时输出的顺序不可预测。

使用场景

当您只关注集合元素的唯一性,并希望插入和查找操作尽可能高效时,可以选择 unordered_set。如:快速去重的哈希检查。

setunordered_set 的选择建议

场景建议使用
需要有序且唯一的集合数据set
只需要唯一集合且关注性能unordered_set
查找频繁,插入、删除不多的集合set
大量插入和查找操作的集合unordered_set

常见的 set 操作方法与注意事项

常见操作

  1. insert(value)

    • 将元素插入 set 中。如果元素已经存在,插入操作会失败(即不会插入重复元素)。
    • 返回值:返回一个 pairfirst 是插入的元素,second 是一个布尔值,指示元素是否成功插入。
  2. erase(value)

    • 删除指定元素。如果元素存在,它将从 set 中移除。
    • 返回值:删除操作返回一个整数,表示删除的元素数量(通常为 0 或 1)。
  3. find(value)

    • 查找指定元素。如果元素存在,返回指向该元素的迭代器;否则,返回 end()
  4. count(value)

    • 返回指定元素在 set 中的出现次数。由于 set 中的元素是唯一的,因此该操作的结果要么是 0,要么是 1。
  5. clear()

    • 删除 set 中的所有元素。
  6. size()

    • 返回 set 中的元素个数。
  7. empty()

    • 如果 set 为空,返回 true,否则返回 false

注意事项

  • 元素的唯一性set 会自动删除重复元素,因此插入重复元素时不会出错,但也不会插入新元素。
  • 元素顺序set 保证元素按升序排列,插入元素时会根据其值自动排序。
  • 性能考虑set 的插入、删除和查找操作时间复杂度为 O(log n),适合中等规模的数据集。如果只关心操作性能,可以考虑使用 unordered_set,它在大多数情况下能提供常数时间复杂度的操作。

常见问题解答

  1. 为什么插入重复元素时不会成功?

    • setunordered_set 的特性是只存储唯一的元素,因此不会添加相同值的元素。
  2. 我可以手动控制 unordered_set 中的元素顺序吗?

    • 不可以,unordered_set 中的元素顺序完全取决于哈希表结构。

总结

  • set 是基于树的有序集合,适用于需要顺序保证的情况。
  • unordered_set 基于哈希表,适合无序、高效的数据存储需求。

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

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

相关文章

【软服之家-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

海外营销新利器:米壳AI视频编辑工具全解析

抖知书老师推荐&#xff1a; 随着AI技术的飞速发展&#xff0c;跨境电子商务领域迎来了新的变革。今天&#xff0c;我要向大家介绍一款名为米壳Medio.cool的AI视频营销工具&#xff0c;它专为企业出海而生&#xff0c;助力商品在全球市场上的推广。 米壳Medio.cool以其AI驱动…

常见 HTTP 状态码分类和解释及服务端向前端返回响应时的最完整格式

目前的开发项目&#xff0c;准备明年的国产化&#xff0c;用了十年的自研系统借这个机会全部重写&#xff0c;订立更严格的规范&#xff0c;这里把返回格式及对应状态码记录一下。 常见 HTTP 状态码及解释 HTTP 状态码用于表示客户端请求的响应状态&#xff0c;它们分为五类&a…

Docker在CentOS上的安装与配置

前言 随着云计算和微服务架构的兴起&#xff0c;Docker作为一种轻量级的容器技术&#xff0c;已经成为现代软件开发和运维中的重要工具。本文旨在为初学者提供一份详尽的指南&#xff0c;帮助他们在CentOS系统上安装和配置Docker及相关组件&#xff0c;如Docker Compose和私有…

echart折线图动感设计

效果&#xff1a; 起由&#xff1a; 需求设计大大觉得EChart图表的折线图太过于死板&#xff0c;没有交互感&#xff0c;希望可以实现上图的效果&#xff0c;经过一顿摸索发现EChart折线图effect属性可以让光点沿着折线的路径移动&#xff0c;从而实现动态效果&#xff0c;注意…

2-2.STM32之定时器TIM---输入捕获--实验2( PWMI模式测频率占空比)

输入捕获模式测频率、PWMI模式测频率占空比-CSDN博客 参考这篇文章&#xff01; 来利用一个GPIO的定时器的两个通道进行捕获占空比和频率&#xff0c;看出可以看出。TI1FP1和TI2FP2&#xff0c;计数值分别在CCR1和CCR2中取&#xff0c; 测周法 IC.c #include "stm32f1…

mathtype中自定义数组维数问题

1 选中红框里的内容 2 设置矩阵维数&#xff0c;即行列数 3 选中中间数字部分&#xff0c;选中左边大括号&#xff0c;或者快捷键ctrll. ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/39ec0c8ed76a46d8b83d484a84ac59a7.png选中内部a

普吕克线( Plücker 线)

普吕克线 在 Plcker 坐标表示中&#xff0c;一条直线 l ‾ 1 \underline{l}_1 l​1​可以用以下两个向量来表示&#xff1a; l ‾ 1 l 1 ϵ m 1 \underline{l}_1 l_1 \epsilon m_1 l​1​l1​ϵm1​ 方向向量 l 1 l_1 l1​&#xff1a;表示直线的方向。动量向量 m 1 m_…

SLMi350DB-DG适用于驱动低边侧和高边侧的MOSFET和IGBT 兼容光耦的单通道隔离驱动器

SLMi350DB-DG是一款兼容光耦的单通道隔离驱动器&#xff0c;具有4A/7A源电流/灌电流以及3.75kVRMS隔离耐压值&#xff0c;适用于驱动低边侧和高边侧的MOSFET和IGBT。与光耦栅极驱动器相比&#xff0c;SLMi350DB-DG具有高共模瞬态抗扰度(CMTI)、低传播延迟和较小的脉宽失真等关键…

帕金森患者必看!这些维生素能帮你改善生活质量!

帕金森病&#xff0c;这个看似遥远的疾病&#xff0c;却悄然影响着许多人的生活质量。作为一种慢性神经退行性疾病&#xff0c;帕金森不仅会导致患者的运动能力受限&#xff0c;还会引发一系列非运动性症状&#xff0c;如便秘、情绪波动等。然而&#xff0c;你知道吗&#xff1…

5G智能对讲终端|北斗有源终端|北斗手持机|单兵|单北斗

在当今这个快速发展的数字化时代&#xff0c;5G技术的广泛应用正以前所未有的速度推动着各行各业的变革。作为这一技术浪潮中的重要一环&#xff0c;5G智能终端QM630D凭借其卓越的性能和多样化的功能&#xff0c;在林业、渔业、安保、电力、交通等多个领域展现出了巨大的应用潜…

【comfyui教程】ComfyUI有趣工作流推荐:快速换脸,创意随手掌握!

前言 在数字影像处理和创意表达领域&#xff0c;ComfyUI 绝对是你的得力助手&#xff01;今天我们推荐一个非常有趣的工作流——快速换脸。无论你是图像编辑小白&#xff0c;还是深耕AI影像的达人&#xff0c;这个工作流都能让你快速实现面部迁移&#xff0c;体验全新的照片玩…

GPT原理;ChatGPT 等类似的问答系统工作流程如下;当用户向 ChatGPT 输入一个问题后:举例说明;ChatGPT不是通过索引搜索的传统知识库

目录 GPT原理 GPT架构 GPT 主要基于 Transformer 的解码器部分 ChatGPT 等类似的问答系统工作流程如下: 用户输入 文本预处理 模型处理 答案生成 输出回答 当用户向 ChatGPT 输入一个问题后:举例说明 文本预处理: ChatGPT不是通过索引搜索的传统知识库 GPT GPT…

Linux云计算 |【第五阶段】CLOUD-DAY8

主要内容&#xff1a; 掌握DaemonSet控制器、污点策略&#xff08;NoSchedule、Noexecute&#xff09;、Job / CronJob资源对象、掌握Service服务、服务名解析CluterIP&#xff08;服务名自动发现&#xff09;、&#xff08;Nodeport、Headless&#xff09;、Ingress控制器 一…

基于Zynq FPGA对雷龙SD NAND的测试

一、SD NAND 特征 1.1 SD 卡简介 雷龙的 SD NAND 有很多型号&#xff0c;在测试中使用的是 CSNP4GCR01-AMW 与 CSNP32GCR01-AOW。芯片是基于 NAND FLASH 和 SD 控制器实现的 SD 卡。具有强大的坏块管理和纠错功能&#xff0c;并且在意外掉电的情况下同样能保证数据的安全。 …

探索空间计算与 VR 设备的未来:4K4DGen 高分辨率全景 4D 内容生成系统

在当今科技飞速发展的时代,空间计算和 VR 设备正逐渐成为人们体验沉浸式场景的重要工具。而今天,我们要为大家介绍一款具有创新性的技术 ——4K4DGen 高分辨率全景 4D 内容生成系统,它为 VR/AR 沉浸式体验带来了全新的可能性。 一、项目概述 4K4DGen 项目的核心目标是实现 …

使用官网tar包制作OpenSSL及OpenSSH rpm包进行升级安装(OpenSSH_9.9p1, without OpenSSL未解决)

一、制作openssl-1.1.1w.rpm包 1、安装基础依赖包和rpmbuild及其依赖包 yum install curl which make gcc perl perl-WWW-Curl rpm-build rpm-build rpmdevtools tree -y yum install gcc-c glibc glibc-devel openssl openssl-devel \pcre-devel zlib zlib-devel perl…

Node.js回调函数以及事件循环使用介绍(基础介绍 三)

回调函数 Node.js 异步编程的直接体现就是回调。 异步编程依托于回调来实现&#xff0c;但不能说使用了回调后程序就异步化了。 回调函数在完成任务后就会被调用&#xff0c;Node 使用了大量的回调函数&#xff0c;Node 所有 API 都支持回调函数。 例如&#xff0c;我们可以…

Linux(CentOS)安装 MySQL

CentOS版本&#xff1a;CentOS 7 MySQL版本&#xff1a;MySQL Community Server 8.4.3 LTS 1、下载 MySQL 打开MySQL官网&#xff1a;https://www.mysql.com/ 直接下载网址&#xff1a;https://dev.mysql.com/downloads/mysql/ 其他版本 2、上传 MySQL 文件到 CentOS 使用F…

服务器被攻击排查记录

起因 我的深度学习的所有进程突然被killed&#xff0c;我以为是检修&#xff0c;后面发现好像简单的python代码可以正常运行。但是我的训练进程一启动就会被killed 第一时间没有用htop查看cpu&#xff0c;用top看着挺正常的&#xff0c;但是后面看htop&#xff0c;全是绿的&a…