C++初学者指南-5.标准库(第一部分)--标准库算法介绍

C++初学者指南-5.标准库(第一部分)–标准库算法介绍

文章目录

  • C++初学者指南-5.标准库(第一部分)--标准库算法介绍
    • C++的标准算法是:
    • 第一个示例
    • 组织
    • 输入范围
    • 自定义可调用参数
    • 并行执行(C++17)
    • 迭代器和范围的类别
    • 错误消息
    • 命名空间std::ranges中的算法 (C++20)
    • 算法参数图标
    • 相关内容

C++的标准算法是:

  • 算法构建块
  • 在(迭代器)范围的元素上操作
  • 作为独立功能实现
  • 泛型:以(大部分)与容器/元素无关的方式实现
  • 许多都可以使用 functions对象 / lambda 进行自定义
  • 久经考验且高效

第一个示例

在这里插入图片描述
返回一个迭代器,指向最小的元素,从而同时返回它的位置和值。

#include <vector>
#include <algorithm>  // std::min_element
std::vector<int> v {7,9,3,5,3,2,4,1,8,0};
// smallest in subrange (as shown in image):
auto i = min_element(begin(v)+2, begin(v)+7);
auto min = *i;  // int min = 2
// smallest in entire container:
auto j = min_element(begin(v), end(v));
std::cout << *j << '\n';  // prints '0'
v.erase(j);  // erases smallest element

运行示例代码

组织

#include <algorithm>
非修改查询

  • 查找元素/存在查询
  • 最小值/最大值
  • 比较元素范围
  • 已排序范围的二分搜索

修改操作

  • 复制/移动元素
  • 替换/转换元素
  • 删除元素
  • 排序范围的并集/交集/等

#include <numeric>
数值范围的操作(求和,减法,……)
#include <ranges>
可组合的范围视图,范围工具。
#include <iterator>
迭代器工具(距离,下一个,…)
#include <memory>
对未初始化内存的操作

C++20

  • 大多数标准算法的改进和更易使用的版本
  • 范围和视图适配器
  • 更严格地处理算法输入要求(基于“Concepts ”)

输入范围

Iterators迭代器
标准算法使用迭代器 遍历/访问输入元素。

  • 允许独立于容器类型实现算法
  • 无需每种容器类型都实现同一种算法
  • 新(第三方)容器可以与现有的标准算法实现一起使用

Iterator Ranges迭代器范围
= 迭代器对 p,q
在这里插入图片描述
注意:迭代器q指向范围内最后一个元素的后一个位置
在这里插入图片描述

作为输入范围对象(C++20)


在这里插入图片描述

#include <vector>
#include <algorithm>  // std::ranges::min_element
std::vector<int> v {3,5,3,2,4,1};
auto j = std::ranges::min_element(v);
std::cout << *j <<'\n';  // prints '1'

运行示例程序

C++20 命名空间 std::ranges 中的算法

  • 还接受单个范围对象,比如容器或视图作为输入(在 C++20 之前:只接受迭代器对)。
  • 必须在完整的命名空间中调用(在c++中是命名空间限定的),因为无法通过参数依赖查找(=在其参数的命名空间中查找函数)找到它们。
  • 所谓范围,就是任何对象r,只要std::ranges::begin®和std::ranges::end®返回的要么是有效的迭代器,要么是表示范围结束的哨兵。

自定义可调用参数

许多标准算法都可以通过传递可调用实体(如函数、lambda表达式或自定义函数对象)作为参数来定制:

在这里插入图片描述
min_element的第二个版本接受一个可调用实体作为第三个参数,用于比较元素对,而第一个版本使用<运算符。

示例:使用自定义类型的min_element

#include <vector>
#include <algorithm>
struct P { int q; char c; };
std::vector<P> v { {2,'c'}, {1,'b'}, {3,'a'} };

使用函数进行比较

// 根据成员q来比较自定义类型P
bool less_q (P const& x, P const& y) {return x.q < y.q;
}
auto i = min_element(begin(v), end(v), less_q);
auto q1 = i->q;  // int  q1 = 1
auto c1 = i->c;  // char c1 = 'b'

使用lambda进行比较

// 根据成员c,用lambda来比较自定义类型P
auto j = min_element(begin(v), end(v), [](P const& x, P const& y){return x.c < y.c;});
auto q2 = j->q;  // int  q2 = 3
auto c2 = j->c;  // char c2 = 'a'

Lambdas

  • 可以被认为是"匿名函数"
  • 可以在函数内定义(普通的 C++ 函数无法嵌套)
  • 由编译器自动生成类型的函数对象

我们将在以后的章节中学习更多关于函数对象的知识,特别是关于 lambda 表达式。它们不仅极其有用,而且远比上面的示例所暗示的要强大。

并行执行(C++17)

大多数标准算法可以并行执行。
这是通过提供执行策略对象作为第一个参数来配置的。

#include <execution>
…
sort(std::execution::par, begin(v), end(v));
执行政策影响
std::execution::seq不允许并行化和矢量化
std::execution::unseq (C++20)可以矢量化,但不允许并行化
std::execution::par可以并行化,但不允许矢量化
std::execution::par_unseq允许以无序方式调用输入元素访问函数,并在每个线程内彼此之间不按顺序进行操作

编译器支持(最低要求版本)
GNU g++ 9
需要 TBB 库(英特尔线程构建模块)
在 Debian/Ubuntu/WSL 上安装: sudo apt install libtbb-dev
可执行文件需要与 TBB 链接: g++ -std=c++17 … -o exename -ltbb


微软MSVC 19.14(VS 2017 15.7)
Microsoft C++ 团队博客:使用 C++17 并行算法获得更好的性能


NVIDIA NVC++
可以使用NVIDIA GPU来加速C++标准算法:
NVIDIA 开发者博客:使用 stdpar 通过 GPU 加速标准 C++

迭代器和范围的类别

类别 = 支持的迭代器/范围对象操作和保证的集合

  • 基于常见的算法要求(输入、输出、效率、正确性……)
  • 由输入范围对象或提供迭代器的宿主容器确定
Sentinel哨兵迭代器类似的位置指示器;通常用于表示范围的末尾支持== 、 !=
Input输入读取对象的访问权限;可前进到下一个位置
示例:从文件读取值的迭代器
支持 *、 ++、 ==、 !=
Output输出写入对象的访问权限;可前进到下一个位置
示例:将值写入文件的迭代器
支持 *、 ++、 ==、 !=
Forward前向读/写访问;前向遍历,无随机访问
多次保证:可以使用相同范围的迭代器多次访问相同的对象
示例: std::forward_list 的迭代器
支持 *、 ++、 ==、 !=
BiDirectional双向多次保证,双向遍历(但无随机访问)
示例: std::list 的迭代器
支持 *、 ++、 --、 ==、 !=
RandomAccess随机访问随机访问,但不一定是连续的内存块
示例: std::deque 的迭代器
支持 *、 []、 ++、 --、 +=、-=、-、+、 ==、 !=、 <、 <=、 >、 >=

如果您需要有关算法要求的详细信息, 运行时复杂度等请参考 cppreference.com
那里的描述不太适合初学者,但很详细, 通常是最新的并由许多 C++ 专家检查。

错误消息

通用算法可能会非常令人困惑:

std::list x {4,2,8,1};
std::sort(begin(x), end(x));

这个不会编译,因为sort需要随机访问迭代器,而list只提供双向迭代器。GCC 10 的错误消息看起来是这样的:
在这里插入图片描述
默认情况下,通用函数对其输入类型的要求仅在函数实现内部以临时方式进行检查,而不是在调用点处进行检查。
这意味着在实现中使用不支持的操作时,比如 iterator1 - iterator2,会导致编译失败。
注意:在失败信息种,始终查找包含“错误”一词的第一条消息。

命名空间std::ranges中的算法 (C++20)

  • 在调用点使用"Concepts" 检查需求(稍后会详细介绍)
  • 要求总体上更为一致明确
  • 让编译器的错误提示更有帮助,但仍有改进的空间

算法参数图标

本教程在可视化标准算法、函数、容器成员函数等方面使用了以下图形约定:
在这里插入图片描述

相关内容

标准算法概述
标准范围对象算法概述
视频:什么是 C++ 标准库?  (CopperSpice C++)
视频:回归基础:经典 STL  (鲍勃·斯蒂格尔,2021)
视频:C++ Seasoning (Sean Parent,2013)
视频:一小时内掌握 105 个 STL 算法  (Jonathan Boccara,2018)
视频:算法助记符:利用 STL 算法提高工作效率  (Tommy Bennett)
视频:作为表达式的 STL 算法  (Oleksandr Bacherikov,2021)
视频:C++ 标准算法(视频系列)作者:Conor Hoekstra
视频:C++ 迭代器 作者:Conor Hoekstra
书籍:C++ 之旅:容器和算法

[算法概述表]
在这里插入图片描述

容器遍历
标准库最小/最大算法
标准库存在性查询
标准库查找算法
标准库范围比较算法
标准库范围复制算法
标准库序列重新排序算法
标准库逐元素范围修改
标准库删除算法
标准库数值运算
标准库排序序列操作
标准库堆操作
标准库范围实用程序

附上原文链接
如果文章对您有用,请随手点个赞,谢谢!^_^

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

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

相关文章

linux 安装 RocketMQ 4.7

安装介绍 Centos 7RocketMQ 4.7JDK 1.8 (安装JDK参考)RocketMQ的官网地址&#xff1a; http://rocketmq.apache.orgGithub地址是 https://github.com/apach e/rocketmq 安装操作 下载RocketMQ RocketMQ运行版本下载地址&#xff1a; Rocketmq-all-4.7.1-bin-release.zip …

httpx,一个网络请求的 Python 新宠儿

大家好&#xff01;我是爱摸鱼的小鸿&#xff0c;关注我&#xff0c;收看每期的编程干货。 一个简单的库&#xff0c;也许能够开启我们的智慧之门&#xff0c; 一个普通的方法&#xff0c;也许能在危急时刻挽救我们于水深火热&#xff0c; 一个新颖的思维方式&#xff0c;也许能…

AI大模型新纪元:哪四大趋势引领未来智能革命?

在人工智能热潮持续居高不下背景下&#xff0c;虽然全球AI大模型企业卷参数的激烈程度有所放缓&#xff0c;但大模型仍不断朝着万亿、十万亿参数发展&#xff0c;并推动多模态持续演进以通向AGI。同时&#xff0c;大模型也在朝向轻量化、高效化、垂直多元化发展&#xff0c;进而…

每日复盘-20240718

20240718 六日涨幅最大: ------1--------300713--------- 英可瑞 五日涨幅最大: ------1--------301016--------- 雷尔伟 四日涨幅最大: ------1--------301016--------- 雷尔伟 三日涨幅最大: ------1--------301016--------- 雷尔伟 二日涨幅最大: ------1--------300713----…

Linux LVM扩容方法

问题描述 VMware Centos环境&#xff0c;根分区为LVM&#xff0c;大小50G&#xff0c;现在需要对根分区扩容。我添加了一块500G的虚拟硬盘(/dev/sdb)&#xff0c;如何把这500G扩容到根分区&#xff1f; LVM扩容方法 1. 对新磁盘分区 使用fdisk /dev/sdb命令&#xff0c;进…

SpringCloud02_consul概述、功能及下载、服务注册与发现、配置与刷新

文章目录 ①. Euraka为什么被废弃②. consul简介、如何下载③. consul功能及下载④. 服务注册与发现 - 8001改造⑤. 服务注册与发现 - 80改造⑥. 服务配置与刷新Refresh ①. Euraka为什么被废弃 ①. Eureka停更进维 ②. Eureka对初学者不友好,下图为自我保护机制 ③. 阿里巴巴…

linux下JDK的安装

前言&#xff1a; 安装部署java开发的代码都需要java环境&#xff0c;这里记录下linux下JDK的安装过程&#xff0c;仅供学习参考。 JDK的下载 下载地址&#xff1a;https://www.oracle.com/java/technologies/downloads 选择和操作系统匹配的版本进行下载 查看操作系统&…

HarmonyOS NEXT学习——@BuilderParam装饰器

初步理解&#xff0c;相当于VUE的插槽slot Builder function overBuilder() {}Component struct Child {label: string ChildBuilder customBuilder() {}Builder customChangeThisBuilder() {}BuilderParam customBuilderParam: () > void this.customBuilder; // 使用自定…

人工智能未来发展前景将会怎样?

当我们探讨人工智能未来的发展前景时&#xff0c;可以从多个角度来详细说明其可能的影响和趋势&#xff1a; 技术进步与应用扩展 1.深度学习与机器学习&#xff1a; 进一步优化和算法进展&#xff1a;深度学习已经取得了巨大成就&#xff0c;但仍面临挑战&#xff0c;如对小数…

浅说区间dp(下)

文章目录 环形区间dp例题[NOI1995] 石子合并题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2006 提高组] 能量项链题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路 [NOIP2001 提高组] 数的划分题目描述输入格式输出格式样例 #1样例输…

你也许不知道,自己可能是一个「热人」

稍微标题党了一下。: ) 今天想跟大家分享的&#xff0c;是一种很少有人了解的人格特质。它非常普遍&#xff0c;许多人都或多或少有一些倾向&#xff0c;但却很少有人意识到它。 不妨看一看&#xff0c;你有没有下面这些特征&#xff1a; 有着极其旺盛的求知欲&#xff0c;对许…

paddleocr icdar2015数据集训练dbnet检测模型

参考&#xff1a;https://github.com/PaddlePaddle/PaddleOCR/blob/main/doc/doc_ch/detection.md 原理 DBNET论文 Real-time Scene Text Detection with Differentiable Binarization 参考&#xff1a;https://blog.csdn.net/qq_35756383/article/details/118679258 Real-T…

【STC89C51单片机】定时器/计数器的理解

目录 定时器/计数器1. 定时器怎么定时简单理解&#xff08;加1经过了多少时间&#xff09;什么是时钟周期什么是机器周期 2.如何设置定时基本结构相关寄存器1. TMOD寄存器2. TCON寄存器 代码示例 定时器/计数器 STC89C51单片机的定时器和计数器&#xff08;Timers and Counter…

【BUG】已解决:NameError: name ‘XXX‘ is not defined

已解决&#xff1a;NameError: name ‘XXX‘ is not defined 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&#xff0c;热衷分享知识&#xff0c;武汉城市开发者社…

Harmony 状态管理 @Local 和 @Param

Harmony 状态管理 Local 和 Param Local 背景 Local 是harmony应用开发中的v2版本中 对标**State**的状态管理修饰器&#xff0c;它解决了 State 对状态变量更改的检测混乱的问题&#xff1a; State 修饰的状态变量 可以是组件内部自己定义的State 修饰的状态 也可以由外部父…

路径规划 | 基于DQN深度强化学习算法的路径规划(Matlab)

目录 效果一览基本介绍程序设计参考文献 效果一览 基本介绍 DQN路径规划算法 基于深度强化学习算法的路径规划 matlab2023b 栅格环境&#xff0c;走迷宫&#xff0c;可以通过窗口界面方便观察交互过程&#xff0c;代码注释详尽。 程序设计 完整源码和数据私信博主回复基于DQN深…

Vue学习---vue cli 项目创建

使用的编辑工具webStorm 创建例子: hello vue create hello 选择 vue3 进行创建 运行 npm run serve 测试访问&#xff1a;http://localhost:8080 改动内容重新编译&#xff1a; npm run build dist 目录就是编译后的可运行内容

1分钟带你了解苹果手机删除照片恢复全过程

在日常使用苹果手机时&#xff0c;我们可能会不小心删除掉一些重要的照片&#xff0c;这让人非常烦恼。那么苹果手机怎么恢复删除的照片&#xff1f;下面小编将会向大家介绍苹果手机恢复删除的照片的方法&#xff0c;帮助大家轻松找回你丢失的照片。 一、利用“最近删除”文件夹…

甲骨文面试题【动态规划】力扣377.组合总和IV

给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3], target 4 输出&#xff1a;7 解释&#x…

【Linux】详解加锁实现线程互斥

一、多线程不加线程互斥可能会引发的问题 下面是一个抢标逻辑。抢票为什么会抢到负数&#xff1a;假设当票数为1时&#xff0c;此时四个进程的判断条件tickets都大于0&#xff0c;都会进入抢票操作&#xff0c;第一个进程抢完票以后tickets0并写回内存&#xff0c;第二个进程再…