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

C++参悟:stl中的比较最大最小操作

stl中的比较最大最小操作

  • 一、概述
  • 二、最小值
    • 1. min
    • 2. min_element
  • 三、最大值
    • 1. max
    • 2. max_element
  • 四、混合
    • 1. minmax
    • 2. minmax_element

一、概述

记录这里C11中常用的最小值和最大值的比较函数,最好的参考资料其实就是 https://zh.cppreference.com

最重要的查看文档其实就看他的如何实现,这个就是使用的最常用的功能。因为STL用的很多基本上全是函数模板库,都是支持自定义函数函数器作为一个对比选项。

不带 _element 的函数一般用在两个值之间比较,如果很多值,还是用带_element ,这个是去遍历容器比较

就像min、max最后比较两个值,而且返回的是值,min_element、max_element比较容器,返回的是迭代器

二、最小值

1. min

1. 可能的实现

// 版本 1
template<class T> 
const T& min(const T& a, const T& b)
{return (b < a) ? b : a;
}// 版本 2
template<class T, class Compare> 
const T& min(const T& a, const T& b, Compare comp)
{return (comp(b, a)) ? b : a;
}// 版本 3
template<class T>
T min(std::initializer_list<T> ilist)
{return *std::min_element(ilist.begin(), ilist.end());
}// 版本 4
template<class T, class Compare>
T min(std::initializer_list<T> ilist, Compare comp)
{return *std::min_element(ilist.begin(), ilist.end(), comp);
}

从上面的实现其实就能看出来,这个是支持用函数器做自己的特定对比,也是可以通过重载 < 符号去实现对比功能.

而且输入值和输出的模板类型是一样的,

还有一些用的是 min_element 函数为实现,对了min_element的一个适配器。

  1. 例子

下面给一个对比最小值的例子

#include <algorithm>
#include <iostream>
#include <string_view>int main()
{int res_1 = std::min(1, 9999);	// res_1 = 1char res_2 = std::min('a', 'b');	// res_2 = 'a'string res_3 = std::min({"foo", "bar", "hello"}, [](const std::string s1, const std::string s2){return s1.size() < s2.size();}) ;	// res_3 = "foo"
}

2. min_element

看看这个的相关实现

// 版本一
template<class ForwardIt>
ForwardIt min_element(ForwardIt first, ForwardIt last)
{if (first == last)return last;ForwardIt smallest = first;++first;for (; first != last; ++first)if (*first < *smallest)smallest = first;return smallest;
}// 版本二
template<class ForwardIt, class Compare>
ForwardIt min_element(ForwardIt first, ForwardIt last, Compare comp)
{if (first == last)return last;ForwardIt smallest = first;++first;for (; first != last; ++first)if (comp(*first, *smallest))smallest = first;return smallest;
}

从函数的实现来看,外部的函数器的差距就在 一个是用得 ‘<’ ,另外一个用的 comp(*first, *smallest)对比,因为‘<’取决于语言定义或者我们程序员的重载实现的。 后面的其他函数max,minmax都是用的这样的。

这个参数的传入的其实就是迭代器,返回的也是迭代器也需要去解引取值之类的。

就像下面这种代码

std::vector<PointF> points{PointF{-1.43, 5.654}, PointF{2.453, 8.654} , PointF{10.453, -2.654}, PointF{14.453, -8.87}};auto x_minmax = std::minmax_element(points.begin(), points.end(), [](const PointF &p1, const PointF &p2){return p1.x() < p2.x();
}) ;

三、最大值

1. max

max和min是一样的定义方式,其实就是把那个大于小于改了一下

2. max_element

这个的实现也比较简单

// 版本一
template<class ForwardIt>
ForwardIt max_element(ForwardIt first, ForwardIt last)
{if (first == last)return last;ForwardIt largest = first;++first;for (; first != last; ++first)if (*largest < *first)largest = first;return largest;
}// 版本二
template<class ForwardIt, class Compare>
ForwardIt max_element(ForwardIt first, ForwardIt last, Compare comp)
{if (first == last)return last;ForwardIt largest = first;++first;for (; first != last; ++first)if (comp(*largest, *first))largest = first;return largest;
}

四、混合

1. minmax

实现的源码大差不差的如下,是不是比较巧妙和灵活,注意这个是返回的是值,而不是迭代器

//版本一
template<class T> 
constexpr std::pair<const T&, const T&> minmax( const T& a, const T& b )
{return (b < a) ? std::pair<const T&, const T&>(b, a): std::pair<const T&, const T&>(a, b);
}//版本二
template<class T, class Compare> 
constexpr std::pair<const T&, const T&> minmax( const T& a, const T& b, Compare comp )
{return comp(b, a) ? std::pair<const T&, const T&>(b, a): std::pair<const T&, const T&>(a, b);
}//版本三
template< class T >
constexpr std::pair<T, T> minmax( std::initializer_list<T> ilist )
{auto p = std::minmax_element(ilist.begin(), ilist.end());return std::pair(*p.first, *p.second);
}// 版本四
template< class T, class Compare >
constexpr std::pair<T, T> minmax( std::initializer_list<T> ilist, Compare comp )
{auto p = std::minmax_element(ilist.begin(), ilist.end(), comp);return std::pair(*p.first, *p.second);
}

上面的first是小值,second是大值,所以看一下源码就记住了
看看例子

std::pair<int, int> bounds = std::minmax(3, -1);

2. minmax_element

和之前的min_element类似,返回的是一个std::pair<迭代器,迭代器>类型,要取值要自己去解引数据

//版本一
template<class ForwardIt>
std::pair<ForwardIt, ForwardIt> minmax_element(ForwardIt first, ForwardIt last)
{using value_type = typename std::iterator_traits<ForwardIt>::value_type;return std::minmax_element(first, last, std::less<value_type>());
}//版本二
template<class ForwardIt, class Compare>
std::pair<ForwardIt, ForwardIt> minmax_element(ForwardIt first, ForwardIt last, Compare comp)
{auto min = first, max = first;if (first == last || ++first == last)return {min, max};if (comp(*first, *min)) {min = first;} else {max = first;}while (++first != last) {auto i = first;if (++first == last) {if (comp(*i, *min)) min = i;else if (!(comp(*i, *max))) max = i;break;} else {if (comp(*first, *i)) {if (comp(*first, *min)) min = first;if (!(comp(*i, *max))) max = i;} else {if (comp(*i, *min)) min = i;if (!(comp(*first, *max))) max = first;}}}return {min, max};
}

例子如下:

std::vector<int> v {3, 1, 4, 1, 5, 9, 2, 6};
auto bounds = std::minmax_element(v.begin(), v.end());int min = *bounds.first;	// 1
int max = *bounds.second;	// 9

相关文章:

C++参悟:stl中的比较最大最小操作

stl中的比较最大最小操作 一、概述二、最小值1. min2. min_element 三、最大值1. max2. max_element 四、混合1. minmax2. minmax_element 一、概述 记录这里C11中常用的最小值和最大值的比较函数&#xff0c;最好的参考资料其实就是 https://zh.cppreference.com 最重要的查…...

JAVA读取netCdf文件并绘制热力图

读取netCdf的依赖 <dependency><groupId>ucar</groupId><artifactId>netcdfAll</artifactId><version>5.5.3</version><scope>system</scope><exclusions><exclusion><groupId>org.slf4j</groupId…...

数据结构——八大排序

一.排序的概念和其应用 1.1排序的概念 排序&#xff1a;排列或排序是将一组数据按照一定的规则或顺序重新组织的过程&#xff0c;数据既可以被组织成递增顺序&#xff08;升序&#xff09;&#xff0c;或者递减顺序&#xff08;降序&#xff09;。稳定性&#xff1a;假定在待…...

【Unity】RPG2D龙城纷争(十九)流程与UI界面(终章)

更新日期:2024年8月1日。 项目源码:第五章发布(正式开始游戏逻辑的章节) 索引 简介一、游戏流程1.初始化流程2.开始流程3.关卡流程4.关卡结束流程5.启用所有流程二、UI界面逻辑1.开始界面2.存档界面3.关卡界面DataRegion 数据显示逻辑区域RoundRegion 回合逻辑区域RoleMenu…...

C#类和结构体的区别

1、类class是引用类型&#xff0c;多个引用类型变量的值会互相影响。存储在堆&#xff08;heap&#xff09;上 2、结构体struct是值类型&#xff0c;多个值类型变量的值不会互相影响。存储在栈&#xff08;stack&#xff09;上 类结构关键字classstruct类型引用类型值类型存储…...

【RabbitMQ】RabbitMQ持久化

一、简介 RabbitMQ的持久化机制是一种确保数据在RabbitMQ服务重启或异常情况下不会丢失的重要特性。RabbitMQ的持久化主要包括三个方面的内容&#xff1a;交换器的持久化、队列的持久化、消息的持久化。 二、交换器的持久化 1、实现方式 在RabbitMQ中&#xff0c;实现交换器…...

算法刷题笔记 Kruskal算法求最小生成树(详细算法介绍,详细注释C++代码实现)

文章目录 题目描述基本思路实现代码 题目描述 给定一个n个点m条边的无向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。求最小生成树的树边权重之和&#xff0c;如果最小生成树不存在则输出impossible。 最小生成树的概念&#xff1a;给定一张边带权的无向…...

5年经验的软件测试人员,碰到这样的面试题居然会心虚......

我们这边最近的面试机会比较多&#xff0c;但是根据他们的反馈&#xff0c;结束后大部分都没音信了&#xff0c;因为现在企业面试问的非常多&#xff0c;范围非常广&#xff0c;而且开放性的问题很多&#xff0c;很多人即便面试前刷了成百上千道面试题&#xff0c;也很难碰到一…...

C#进阶-轻量级ORM框架Dapper的使用教程与原理详解

本文详细介绍了Dapper在C#中的使用方法&#xff0c;包括Dapper的基本概念、与其他持久层框架的比较、基本语法和高级语法的使用&#xff0c;并通过实例讲解了如何在项目中集成和使用Dapper。Dapper以其高效的性能和简洁的API受到开发者的青睐&#xff0c;适用于各种数据库操作需…...

Windows图形界面(GUI)-MFC-C/C++ - 编辑框(Edit Control) - CEdit

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 编辑框(Edit Control) - CEdit 基本概念 成员函数 示例代码 编辑框(Edit Control) - CEdit 基本概念 编辑框&#xff08;Edit Control&#xff09;是一个允许用户输入和编辑文本的窗…...

网络安全防御【IPsec VPN搭建】

目录 一、实验拓扑图 二、实验要求 三、实验思路 四、实验步骤&#xff1a; 修改双机热备的为主备模式&#xff1a; 2、配置交换机LSW6新增的配置&#xff1a; 3、防火墙&#xff08;FW4&#xff09;做相关的基础配置&#xff1a; 4、搭建IPsec VPN通道 &#xff08;1…...

java环境配置与tomcat的配置

1、java环境配置 一、JDK下载 访问Oracle官网&#xff1a; 前往Oracle官网&#xff08;Oracle | Cloud Applications and Cloud Platform&#xff09;&#xff0c;在首页的顶部菜单中选择“Resources” > “Downloads” > “Java” > “JDK”。注意&#xff1a;Orac…...

OD C卷 - 来自异国的客人/幸运数字

来自异国的客人/幸运数字&#xff08;100&#xff09; 输入描述&#xff1a; 输入k,n,m k表示物品价值&#xff08;十进制&#xff09; k>0 n表示幸运数字, n > 0 m表示异国采用的进制&#xff1b;m > 1 n < m 输出描述&#xff1a; 输出幸运数字的个数&#xff0…...

C++ | 动态内存管理 new、delete (用法、底层)详解

目录 简单回顾C语言动态内存管理 new、delete的用法 内置类型 new delete 自定义类型 new、delete底层讲解&#xff08;重要&#xff09; operator new 与 operator delete 定位 new 结语 简单回顾C语言动态内存管理 在C语言的学习阶段 我们接触到了三个能在堆上开辟…...

【C语言】结构体内存布局解析——字节对齐

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html &#x1f381;代码托管:黄灿灿 (huang-cancan-xbc) - Gitee.com ⚙️操作环境:Visual Studio 2022 目录 一、引言 二、什么是字节对齐&…...

模型表达方式

目录 一、模型表达概述 二、模型精确表达 2.1 几何表示 (Geometrical Representation) 三、模型非精确表达 3.1 网格表示 (Mesh Representation) 3.2 体素表示 (Voxel Representation) 一、模型表达概述 模型的表达方式多种多样,选择适合的表达方式取决于具体应用场景和…...

校园课程助手【4】-使用Elasticsearch实现课程检索

本节将介绍本项目的查询模块&#xff0c;使用Elasticsearch又不是查询接口&#xff0c;具体流程如图所示&#xff08;如果不了解Elasticsearch可以使用sql语句进行查询&#xff09;&#xff1a; 这里是两种方法的异同点&#xff1a; Mysql&#xff1a;擅长事务类型操作&#…...

经典运维面试题

1、Linux常见的日志文件都有哪些&#xff0c;各自的用途&#xff1f;日志轮询配置文件在哪里&#xff1f;欢迎界面配置文件在哪里&#xff1f; /var/log/messages #内核及公共消息日志/var/log/cron #计划任务日志/var/log/dmesg #系统引导日志/var/log/malilog #邮件系…...

别再盲目推广了!Xinstall助你开启App线下推广新篇章

在这个数字化飞速发展的时代&#xff0c;App已经成为我们生活中不可或缺的一部分。然而&#xff0c;App市场的竞争也日益激烈&#xff0c;如何让你的App在众多竞争者中脱颖而出&#xff0c;成为每个推广者必须面对的问题。今天&#xff0c;就让我们一起探讨一下App线下推广的痛…...

大厂linux面试题攻略五之数据库管理

一、数据库管理-MySQL语句 0.MySQL基本语句&#xff1a; 1.SQL语句-增 创建xxx用户&#xff1a; mysql>create user xxx % indentified by 123456; xxx表示用户名 %b表示该用户用来连接数据库的方式&#xff08;远程或本地连接&#xff09; indentified by 123456设置密码…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式&#xff0c;可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...