重学C++ | std::set 的原理
std::set 是C++标准库中的容器之一,它基于红黑树实现。std::set 利用红黑树的特性来实现有序的插入、查找和删除操作,并且具有较好的平均和最坏情况下的时间复杂度。
当向 std::set 插入元素时,它会按照特定的比较函数(bool less<T>::operator() const(const T &lhs, const T & rhs))将新元素插入到红黑树的适当位置,以保持树的有序性质。插入操作的平均时间复杂度为 O ( log n ) O(\log n) O(logn),其中 n n n是 std::set 中元素的数量。查找操作(find())使用红黑树的性质,通过比较函数在树中进行二分查找,查找操作的平均时间复杂度为 O ( log n ) O(\log n) O(logn)。
但是当我们把 struct 放入 std::set 会有什么后果呢?因为 std::set 需要在插入到时候排序,所以需要重载 struct 的比较运算符,这个时候就出现问题了,首先我们定义一个结构体 Person :
struct Person {Person(int _ID, string _name, int _age) : ID(_ID), age(_age), name(_name) {}int ID;int age;string name;
};
当我们直接插入到 std::set<Person> 中时,会报 complier error 的错误,因此简单补写一个比较运算符重载,如下:
bool operator<(const Person &lhs, const Person &rhs) {return lhs.age < rhs.age;
}
OK,编译起来没有问题,但是我们运行测试一下下面的find操作就会发现问题
#include <iostream>
#include <set>using namespace std;struct Person {Person(int _ID, string _name, int _age) : ID(_ID), age(_age), name(_name) {}int ID;int age;string name;
};bool operator<(const Person &lhs, const Person &rhs) {return lhs.age < rhs.age;
}int main() {set<Person> person;for (int i = 0; i < 1000; ++i) {Person p_tmp(i, "sxj", 10);person.insert(p_tmp);}Person p(2000, "sxj", 10);auto it = person.find(p);if (it != person.end())cout << "Find Person --- ID: " << it->ID << " name: " << it->name << " age: " << it->age;elsecout << "Can't find" << endl;return 0;
}

明明不在set中的 ID-2000 的Person也可以被找到。造成这个结果的原因是我们所提供的 operator<() ,当Person p1、p2,在 p1<p2 与 p2<p2 都不成立时,find 就会判断 p1 和 p2 是同一个 Person ,因此会造成这样的错误结果。
解决方案就是补充完整我们的比较运算符重载,完整代码如下:
#include <iostream>
#include <set>using namespace std;struct Person {Person(int _ID, string _name, int _age) : ID(_ID), age(_age), name(_name) {}int ID;int age;string name;
};bool operator<(const Person &lhs, const Person &rhs) {if (lhs.ID < rhs.ID) return true;if (lhs.ID > rhs.ID) return false;if (lhs.name < rhs.name) return true;if (lhs.name > rhs.name) return false;return lhs.age < rhs.age;
}int main() {set<Person> person;for (int i = 0; i < 1000; ++i) {Person p_tmp(i, "sxj", 10);person.insert(p_tmp);}Person p(2000, "sxj", 10);auto it = person.find(p);if (it != person.end())cout << "Find Person --- ID: " << it->ID << " name: " << it->name << " age: " << it->age;elsecout << "Can't find" << endl;return 0;
}
相关文章:
重学C++ | std::set 的原理
std::set 是C标准库中的容器之一,它基于红黑树实现。std::set 利用红黑树的特性来实现有序的插入、查找和删除操作,并且具有较好的平均和最坏情况下的时间复杂度。 当向 std::set 插入元素时,它会按照特定的比较函数(bool less<…...
AnV-X6使用及总结
目录 1 简介2 安装3 基础概念3.1 画布Graph3.2 基类Cell3.3 节点Node3.4 边Edge 4 使用4.1 创建节点4.2 节点连线4.3 事件系统 5 总结 1 简介 AntV是一个数据可视化(https://x6.antv.antgroup.com/)的工具(https://antv.vision/zh/ …...
Go 围炉札记
文章目录 一、安装二、文档三、使用 一、安装 VSCode 和 CLion 为 Go 开发配置Visual Studio Code | Microsoft Learn VScode下配置Go语言开发环境【2023最新】 基础篇:新手使用vs code新建go项目 vscode里安装Go插件和配置Go环境 GO 笔记 Golang 配置代理 golang…...
数据分析回头看2——重复值检查/元素替换/异常值筛选
0、前言: 这部分内容是对Pandas的回顾,同时也是对Pandas处理异常数据的一些技巧的总结,不一定全面,只是自己在数据处理当中遇到的问题进行的总结。 1、当数据中有重复行的时候需要检测重复行: 方法:使用p…...
什么是OSPF?为什么需要OSPF
【微|信|公|众|号:厦门微思网络】 【微思网络www.xmws.cn,成立于2002年,专业培训21年,思科、华为、红帽、ORACLE、VMware等厂商认证及考试,以及其他认证PMP、CISP、ITIL等】 什么是OSPF? 开放式最短路径优…...
轻量级的日志采集组件 Filebeat 讲解与实战操作
文章目录 一、概述二、Kafka 安装三、Filebeat 安装1)下载 Filebeat2)Filebeat 配置参数讲解3)filebeat.prospectors 推送kafka完整配置1、filebeat.prospectors2、processors3、output.kafka 4)filebeat.inputs 与 filebeat.pros…...
C# 委托和事件
C# 委托和事件 委托匿名方法事件 委托 当要把方法传送给其他方法时,需要使用委托。首先定义要使用的委托,对于委托,定义它就是告诉编译器这种类型的委托代表了哪种类型的方法,然后创建该委托的一个或多个实例。编译器在后台将创建…...
数据结构与算法之字典: Leetcode 349. 两个数组的交集 (Typescript版)
两个数组的交集 https://leetcode.cn/problems/intersection-of-two-arrays/description/ 题目和解题参考 https://blog.csdn.net/Tyro_java/article/details/133279737 使用字典来解题的算法实现 字典:顾名思义,像新华字典一样可查找,基…...
day-56 代码随想录算法训练营(19)动态规划 part 16
538.两个字符串的删除操作 思路一: 1.dp存储:以word1[i-1]结尾,word2[j-1]结尾,最少进行dp[i][j]次操作2.动态转移方程: if(word1[i-1]word2[i-1]) dp[i][j]dp[i-1][j-1]; else dp[i][j]min(dp[i-1][…...
蓝桥等考Python组别四级005
第一部分:选择题 1、Python L4 (15分) 字符“0”的ASCII码值为48,则字符“5”的ASCII码值为( )。 3953120240正确答案:B 2、Python L4 (15分) 下面哪个是Python中正确的变量名?( ) ABC#sup01Trueif正确答案:B...
【Linux】diff 命令
【Linux】diff 命令——并排格式输出 功能 diff 以逐行的方式,比较文本文件的异同处。 如果指定要比较目录,则 diff 会比较目录中相同文件名的文件,但不会比较其中子目录 diff [参数] [文件A] [文件B]diff [参数] [目录A] [目录B]【参数】…...
【51单片机】9-定时器和计数器
1.定时器的介绍 1.什么是定时器 (1)SoC的一种内部的外设【在单片机里面,但是在CPU外面】 (2)定时器就是CPU的”闹钟“ 2.什么是计数器 (1)定时器就是用计数的原始实现的 (2…...
2023年海南省职业院校技能大赛(高职组)信息安全管理与评估赛项规程
2023年海南省职业院校技能大赛(高职组) 信息安全管理与评估赛项规程 一、赛项名称 赛项名称:信息安全管理与评估 英文名称:Information Security Management and Evaluation 赛项组别:高等职业教育 赛项归属产业&…...
大模型深挖数据要素价值:算法、算力之后,存储载体价值凸显
文 | 智能相对论 作者 | 叶远风 18.8万亿美元,这是市场预计2030年AI推动智能经济可产生的价值总和,其中大模型带来的AI能力质变无疑成为重要的推动力量。 大模型浪潮下,业界对AI发展的三驾马车——算力、算法、数据任何一个维度的关注都到…...
AI文章,AI文章生成工具
在互联网时代,随着信息爆炸式增长,文章的需求愈发旺盛。从博客、新闻、社交媒体到企业宣传,文字作为传达信息、吸引受众的工具变得愈发重要。但问题是,对于很多人来说,创作一篇高质量的文章并不容易。时间、创意、写作…...
mac有必要用清理软件吗?有哪些免费的清理工具
当我们谈到Mac电脑时,很多人都会觉得它比Windows系统更加稳定和高效,也更不容易积累垃圾文件。但实际上,任何长时间使用的操作系统都会逐渐积累不必要的文件和缓存。那么,对于Mac用户来说,有必要使用专门的清理软件吗&…...
React 全栈体系(十八)
第九章 React Router 6 二、代码实战 6. 路由的 params 参数 6.1 routes /* src/routes/index.js */ import About from "../pages/About"; import Home from "../pages/Home"; import Message from "../pages/Message"; import News from &q…...
TCP/UDP
TCP:可靠的有序传输 TCP是一种面向连接的协议,旨在提供可靠、有序的数据传输。它通过以下方式实现这一目标: 1. 连接建立和维护 在使用TCP传输数据之前,必须先建立连接。这个过程包括三次握手,即客户端和服务器之间…...
c++内存对齐
原文在这里。https://blog.csdn.net/WangErice/article/details/103598081 但是内容有错误。我在自己的这里修改并变成红色了。 内存在使用过程并不是单一的依次排列,而是按照某种既定的规则来进行对齐,以方便快速访问.内存的对齐原则有以下三条&#…...
leetcode 33. 搜索旋转排序数组
2023.9.26 本题暴力法可以直接A,但是题目要求用log n的解法。 可以想到二分法,但是一般二分法适用于有序数组的,这里的数组只是部分有序,还能用二分法吗? 答案是可以的。因为数组是经过有序数组旋转得来的,…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错
出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上,所以报错,到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本,cu、torch、cp 的版本一定要对…...
学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
