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/46151.shtml

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

相关文章

TS真的比JS更好吗?

前言 在讨论TypeScript&#xff08;TS&#xff09;是否比JavaScript&#xff08;JS&#xff09;更好时&#xff0c;我们需要明确“更好”这一概念的上下文和衡量标准。TypeScript和JavaScript在多个方面有着明显的区别&#xff0c;但它们并不是简单的“好”与“不好”的关系&a…

国产数据库VastBase与C/C++程序适配

背景 2022年底的项目&#xff0c;记录一下。 某项目后台使用C程序开发&#xff0c;使用的是OCI连接Oracle数据库。现需要做去O国产化适配改造。 本文聊聊C/C应用程序如何使用VastBase替换Oracle。 编译适配 开发包获取 从VastBase官方或接口人处获取OCI开发包&#xff0c;包含…

线程池笔记

笔记梳理 前言.PHONYC标准库头文件C/C通用或C特有头文件mkdirc_str()snprintfvsnprintfumaskopen函数可变参数列表va_startva_endfunctionalstatic_castpthread_cond_init_threads.emplace_backstd::bindstd::placeholdersThreadPool(const ThreadPool<T> &tp) dele…

博客前端项目学习day01

这里写自定义目录标题 登录创建项目配置环境变量&#xff0c;方便使用登录页面验证码登陆表单 在VScode上写前端&#xff0c;采用vue3。 登录 创建项目 检查node版本 node -v 创建一个新的项目 npm init vitelatest blog-front-admin 中间会弹出询问是否要安装包&#xff0c…

前端Vue组件化实践:打造自定义等宽tabs标签组件

在前端开发的世界里&#xff0c;随着业务复杂度的提升和需求的多样化&#xff0c;传统的整体式开发方式已经难以满足快速迭代和高效维护的需求。组件化开发作为一种重要的解决方案&#xff0c;正逐渐受到广大开发者的青睐。本文将结合Vue框架&#xff0c;探讨如何通过组件化开发…

标签-镜像拉取策略-重启策略-pod优雅终止-pod中容器资源限制-容器类型-容器守护进程-日志排错-容器命令exec-cp

一.标签 1.概述&#xff1a; 标签是附加到kubernets对象&#xff08;比如pod&#xff09;上的键值对&#xff0c;标签可以在创建时附加到对象&#xff0c;随后也可以随时添加修改&#xff1b;标签不支持唯一性。 在k8s中大多数资源都是通过标签进行关联的&#xff08;如pod与s…

DP(3) | 0-1背包 | Java | LeetCode 1049, 494, 474 做题总结

1049. 最后一块石头的重量 II 和 LC 416.分割等和子集 类似 思路&#xff08;我没有思路&#xff09;&#xff1a; 两块石头相撞&#xff0c;这里没有想到的一个点是&#xff0c;相撞的两个石头要几乎相似 以示例1为例&#xff0c;stones [2,7,4,1,8,1]&#xff0c;如果从左到…

【数组、特殊矩阵的压缩存储】

目录 一、数组1.1、一维数组1.1.1 、一维数组的定义方式1.1.2、一维数组的数组名 1.2、二维数组1.2.1、二维数组的定义方式1.2.2、二维数组的数组名 二、对称矩阵的压缩存储三、三角矩阵的压缩存储四、三对角矩阵的压缩存储五、稀疏矩阵的压缩存储 一、数组 概述&#xff1a;数…

HyperSD - 会画草图就能玩AI绘画,AI一键手绘,实时同步 本地一键整合包下载

字节跳动的Lightning团队发布的新图像模型蒸馏算法Hyper-SD&#xff0c;是一项在图像处理和机器学习领域的重要进展。这项技术通过创新的方法提升了模型在不同推理步骤下的性能&#xff0c;同时保持了模型大小的精简。 基于这个算法模型&#xff0c;一个很实用的功能出现了&am…

绝区零 双闪 双闪-三轴 工具

绝区零 双闪 双闪-三轴 工具 0. 演示视频 绝区零&#xff1a;≈100%的极致双闪和双闪-三轴 绝区零&#xff1a;手残党也能打双闪-三轴 1. 基本信息 作者: GMCY系列: 工具系列仓库: GitHub | Gitee话题(GitHub): Tools \ ZenlessZoneZero创建时间: 2024/07/14 2. 声明 !!! 使…

【Linux】重定向 | 为什么说”一切皆文件?“

目录 前言 1.文件描述符分配规则 2.dup2 重定向接口 3.重定向 3.1>输出重定向 3.2>>追加重定向 3.3<输入重定向 3.4 shell 模拟实现< > 3.5 理解> 4. 理解“Linux 下一切皆文件” 前言 问&#xff1a;fd 为什么默认从 3 开始&#xff0c;而不是…

LeetCode热题100刷题15:200. 岛屿数量、所有可达路径、118. 杨辉三角、287. 寻找重复数、84. 柱状图中最大的矩形

200. 岛屿数量 借助DFS寻找整个图的连通分量数&#xff0c;DFS将一个连通分量中的节点标记为visited&#xff0c;res记录连通分量数&#xff0c;最后返回res class Solution { public:const int dir[4][2] {1,0,0,1,-1,0,0,-1};void dfs(vector<vector<char>>&a…

代码随想录——不同路径Ⅱ(Leetcode 63)

题目链接 动态规划 class Solution {public int uniquePathsWithObstacles(int[][] obstacleGrid) {int m obstacleGrid.length;int n obstacleGrid[0].length;int[][] dp new int[m][n];// 遇到障碍则从(0,0)到达for(int i 0; i < m && obstacleGrid[i][0] …

前端挑战:Tkinter布局与设计【三种布局】

前端挑战:Tkinter布局与设计【三种布局】 文章目录 前端挑战:Tkinter布局与设计【三种布局】前言Frame 窗口组件代码效果Tkinter的布局grid 网格布局效果展示:代码讲解pack 布局基本使用左右布局place 布局代码预览前言 作为一个前端开发,习惯性的用HTML去解决客户端的问题…

2024.7.14周报

目录 摘要 ABSTRACT 一、文献阅读 一、题目 二、摘要 三、文献解读 一、Introduction 二、KINN框架 三、主要结果 四、Conclusion 二、KAN 一、KAN与MLP区别 二、KAN网络解析 三、激活函数参数化&#xff08;B-splines&#xff09; 三、网络架构代码 摘要 本周…

Kafka基础入门篇(深度好文)

Kafka简介 Kafka 是一个高吞吐量的分布式的基于发布/订阅模式的消息队列&#xff08;Message Queue&#xff09;&#xff0c;主要应用与大数据实时处理领域。 1. 以时间复杂度为O(1)的方式提供消息持久化能力。 2. 高吞吐率。&#xff08;Kafka 的吞吐量是MySQL 吞吐量的30…

输入法发展历史

输入法的发展历史&#xff0c;尤其是中文输入法&#xff0c;是一个相当丰富和多元的话题&#xff0c;它反映了技术进步、用户需求变化以及计算机和移动设备界面设计的演进。以下是一个概览&#xff1a; 早期阶段 1970s&#xff1a;朱邦复在1976年发明了仓颉输入法&#xff0c;…

python:绘制一元四次函数的曲线

编写 test_x4_x2_4x.py 如下 # -*- coding: utf-8 -*- """ 绘制函数 y x^4x^24x-3 在 -2<x<2 的曲线 """ import numpy as np from matplotlib import pyplot as plt# 用于正常显示中文标题&#xff0c;负号 plt.rcParams[font.sans-s…

Amazon EC2 部署Ollama + webUI

最近和同事闲聊&#xff0c;我们能不能内网自己部署一个LLM&#xff0c;于是便有了Ollama webUI的尝试 对于Linux&#xff0c;使用一行命令即可 curl -fsSL https://ollama.com/install.sh | shollama --help Large language model runnerUsage:ollam…

网络规划设计师教程(第二版) pdf

网络规划设计师教程在网上找了很多都是第一版&#xff0c;没有第二版。 所以去淘宝买了第二版的pdf&#xff0c;与其自己独享不如共享出来&#xff0c;让大家也能看到。 而且这个pdf我已经用WPS扫描件识别过了&#xff0c;可以直接CtrlF搜索关键词&#xff0c;方便查阅。 链接…