C++primer(第五版)第十章(泛型算法)

news2024/12/27 11:28:42

10.1概述

大多数算法定义在头文件algorithm中.另外头文件numeric中定义了一组数值泛型算法.

一般情况下算法不直接操作容器,而是通过迭代器来对元素进行处理,因此迭代器令算法不依赖容器,但算法依赖于元素类型的操作.

泛型算法本身不会执行容器的操作,它们只会运行于迭代器之上.算法永远不会改变底层容器的大小,算法可能改变容器中保存的元素的值,但是不会直接添加或删除元素.

10.2初识泛型算法

标准库提供超过100个算法.要全部记住不太现实,本章会通过介绍一些算法来大体上介绍算法的分类.在需要用到算法时可以直接搜索,不用记住这一百多个算法.

10.2.1只读算法

只读算法只会读取范围内的元素,从不改变元素.

#include <numeric>

accumulate(范围(迭代器),范围(迭代器),初始值)

 accumulate返回给出的迭代器范围内的元素总和加上初始值,返回的类型和给定的初始值类型有关.

然而对于只读不改变元素的算法,最好使用cbegin和cend(我上面的写法没啥大问题,但是不严谨,尽管底层算法基本不会出错).但是如果算法返回的是迭代器,并且要通过返回的迭代器修改元素,那么还是使用begin和end.

#include <numeric>

equal(序列1迭代器,序列1迭代器,序列2迭代器)

 equal返回bool值(打印出来是0(false)/1(true)),用于判断两个序列是否一致.我们可以看到序列1要给出两个迭代器来表示范围,而序列2只给出一个迭代器,这是因为算法假定第二个序列至少和第一个序列一样长,只比较序列1的范围的长度,因此使用这类算法时应当注意要确保序列2的长度要大于等于序列1的范围,编译器不会做检测,如果序列2的长度比序列1小,那么会有可能导致严重错误.

用一个单一迭代器表示第二个序列的算法都假定第二个序列至少和第一个序列一样长.

10.2.2写容器元素的算法

#include<algorithm>

fill_n(迭代器,n,val)

 fill_n从迭代器开始,将n个元素的值变成val.

 算法不检查写操作,因此要确保迭代器(包括)之后至少有n个位置来写入val.

back_inserter(容器)

back_inserter返回一个插入迭代器,通过插入迭代器赋值时,相当于对绑定的容器进行push_back操作.

 copy(序列1迭代器,序列1迭代器,序列2迭代器)

 copy将序列1 的元素值拷贝给序列2,序列2至少要包含和序列1一样多的元素.然后copy返回其目的位置迭代器的值,即指向序列2的尾元素之后的位置.

 10.2.3重排容器元素的算法

sort(范围(迭代器),范围(迭代器),谓词(可以暂时忽略))

 sort会默认将范围内的元素从小到大(升序)进行排序,可以通过谓词来修改排序规则(后面说).

 unique(范围(迭代器),范围(迭代器))

 unique将范围内相邻的重复元素消除,仅留下一样,返回一个迭代器指向最后一个不重复元素之后的位置.由于算法不对容器进行操作,因为unique实际上并没有消除元素,而是将重复的元素挪到范围的最后面,因此要彻底去重则需要手动删除.

 10.3定制操作

10.3.1向算法传递函数

前面提过的谓词包括一元谓词和二元谓词,它们的区别在于一个接收一个参数,一个接收两个参数.谓词可以是函数,可以是仿函数,可以是lambda表达式.

10.3.2 lambda表达式

 [捕获列表] (参数列表)->返回值类型{ 函数体}

 其中参数列表(如果没有参数的话)和返回值类型可以忽略,但必须包含捕获列表和函数体,以下是最简单的lambda表达式,不需要参数,直接返回一个字符串,甚至返回值类型都不用写:

[]{
    return "hello world";
}

 和普通函数不同的是,lambda不能拥有默认参数.

find_if(范围(迭代器),范围(迭代器),谓词(可以为lambda))

 返回迭代器,或满足谓词的条件则指向第一个满足条件的元素,否则返回容器的end的拷贝.

 for_each(范围(迭代器),范围(迭代器),谓词(可以为lambda))

将范围内的元素送入谓词中.这个很实用.

 10.3.3 lambda捕获和返回

当以引用方式(&)捕获一个变量时,必须保证在lambda执行时变量是存在的.

尽可能保持lambda的变量捕获简单化,并且应当尽量避免捕获指针或引用.

如果lambda非常复杂的话,不如直接写一个函数.

10.3.4参数绑定

bind函数可以看作是一个通用的函数适配器.

auto newCallable = bind(callable,arg_list)

bind后,调用newCallable时,会同时调用callable,并传递给它arg_list中的参数. 

arg_list(逗号分隔的参数列表)可能包含形如_n的名字,其中n是一个整数,这类参数是占位符,占据着传递给newCallable的位置,例如_1为第一个参数,_2为第二个参数……

对于_n名字,需要对每个这种名字都单独进行using声明:

using std::placeholders::_1;
using std::placeholders::_2;
using std::placeholders::_3;

或者直接:

using namespace std::placeholder;

10.4再探迭代器

除了iterator之外,标准库还定义了额外的几种迭代器:

插入迭代器: insert iterator

流迭代器: streamiterator

反向迭代器: reserve iterator

移动迭代器: move iterator

10.4.1插入迭代器

 当我们通过插入迭代器进行赋值时,迭代器会调用容器的操作来向给定的容器进行插入元素.

10.4.2 iostream迭代器

iostream类型不是容器,但是标准库定义了可以用于这些IO类型对象的迭代器.

10.5泛型算法结构

10.5.1 五类迭代器

 对于向一个算法传递错误类别的迭代器的问题,很多编译器不会给出任何警告或提示.

10.5.2算法形参模式

向输出迭代器写入数据的算法都假定目标空间足够容纳写入的数据.

10.5.3算法命名规范

接受谓词参数的算法基本上都有附加的_if的后缀.

拷贝版本的算法在名字后面都有附加一个_copy.

10.6特定容器算法

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

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

相关文章

XD教程笔记

一、快捷键 选择&#xff1a; V 粘贴外观&#xff1a; ctrl alt V 矩形&#xff1a; R 组件&#xff1a; ctrl K 椭圆&#xff1a; E 向某一方向对齐&#xff1a; ctrl shift 方向键 钢笔&#xff1a; P 100%显示&#xff1a; ctrl 1 文本&#xff1a; T 锁定&a…

SAP ABAP 查表数据接口

查 SAP 表数据的接口 1.使用范例&#xff1a; 字段注释QUERY_TABLE查询的表名FIELDNAME查询的字段ROWCOUNT查询的行数ROWCOUNT查询的行数OPTIONS查询条件FIELDS查询字段的释义和字符长度DATA查询的数据TOTALROWS符合条件数据的行数 FIELDS 结果&#xff1a; 外围系统接口调用…

图像像素操作与二值化

目录 1、图像像素比较 1.1 比较函数 1.2 图像最大值最小值寻找 2、图像像素逻辑操作 3、图像二值化 3.1 固定阈值二值化 3.2 自适应阈值二值化 1、图像像素比较 1.1 比较函数 1.2 图像最大值最小值寻找 Mat img imread("F:/testMap/bijiao.png");Mat white i…

Bootstrap - 【echart】 统计图表基本使用

一. 前言 Bootstrap是一个流行的前端框架&#xff0c;而ECharts是一个流行的可视化库。 Bootstrap可以用来设计网站和应用程序的用户界面&#xff0c;而ECharts可以用来创建交互式和可视化的图表。 chart.js中文文档&#xff1a;http://www.bootcss.com/p/chart.js/docs/ 二.…

MYSQL的基础架构

了解MySQL&#xff08;超详细的MySQL工作原理 体系结构&#xff09; 1.MySQL体系结构 2.MySQL内存结构 3.MySQL文件结构 4.innodb体系结构 一、了解MySQL前你需要知道的 引擎是什么: MySQL中的数据用各种不同的技术存储在文件(或者内存)中。这些技术中的每一种技术都使用不同…

现货白银投资技巧实战教程

交易的实战技巧是指一些能让交易者获利的方法&#xff0c;当中一般都包含重要的操作纪律以及资金的配置策略&#xff0c;目标是要让投资者以合理的风险控制&#xff0c;来赢得持续的利润。现货白银投资技巧实战教程主要有以下几方面的内容&#xff1a; 1、充分了解交易细则。交…

腾讯云服务器新手入门_省钱入口_搭建网站全流程

腾讯云服务器新手指南从云服务器创建、远程连接到云服务器、安装操作系统、使用阿里云服务器建站教程等全流程&#xff0c;腾讯云服务器网分享腾讯云服务器从创建、使用到搭建网站全流程指南&#xff1a; 目录 一&#xff1a;腾讯云服务器创建 二&#xff1a;腾讯云服务器远…

leetcode84. 柱状图中最大的矩形(单调栈-java)

柱状图中最大的矩形 leetcode84. 柱状图中最大的矩形题目描述单调栈加数组优化栈结构解题代码演示用数组来优化栈结构,时间会更快 单调栈专题 leetcode84. 柱状图中最大的矩形 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;https://leetcode.cn/prob…

01、Linux运维发展与学习路线图

目录 一、Linux运维行业前景二、运维相关岗位三、Linux运维岗位薪酬四、Linux运维岗知识框架4.1、常见站点系统架构演变1 单机2 多机3 缓存4 向外扩展5 Docker 4.2 知识体系框架图4.3 技术人员成长的阶段4.4 方法论 一、Linux运维行业前景 流程化、标准化的工作越来越依赖于信…

结构光三维测量几种比较成熟的方法

1.飞行时间发 原理:通过直接测量光传播的时间,确定物体的面型。发射脉冲信号,接受发射回的光,计算距离。 精度:毫米级 优点:原理简单,可避免阴影和遮挡等问题,且仪器便携化。 缺点:精度相对较低 2.莫尔条纹法 原理:采用两组光栅,一个主光栅,一个基准光栅,通过…

vue + element 笔记

1.安装nodejs&#xff0c;cmd中运行 node -v 验证是否成功 2.安装cnpm&#xff0c;cmd中运行 npm install -g cnpm --registryhttps://registry.npm.taobao.org&#xff0c;cmd中 cnpm -v 验证是否成功 3.安装vue-cli&#xff0c;cmd中运行 cnpm install --global vue-cli&…

【Spark】介绍,部署与快速入门

文章目录 介绍核心模块Spark CoreSpark SQLSpark StreamingSpark MLlibSpark GraphX 部署命令行Web UI提交应用Local 模式Standalone配置文件添加 JAVA_HOME 环境变量和集群对应的 master 节点启动集群配置历史服务添加日志存储路径添加日志配置webui 配置高可用 Yarn模式配置文…

老照片修复:模糊褪色有划痕的老旧照片如何修复?

在我们的生活中&#xff0c;照片是记录我们生活的重要方式之一。无论是在手机相册里还是在家中的相册里&#xff0c;我们都有很多珍贵的照片&#xff0c;但是随着时间的推移&#xff0c;照片也会老化&#xff0c;甚至出现褪色、划痕、折痕、破损、发霉等情况&#xff0c;这些情…

java多线程使用与踩坑

SpringBoot使用多线程简单方法&#xff1a;地址 线程安全查阅资料参考&#xff1a;地址 背景&#xff1a; 经过上述资料查看&#xff0c;我想写个方法&#xff08;依靠notify()唤醒&#xff0c;依靠wait()等待&#xff09;实现两个线程轮流打印。 实现&#xff1a; 1.线程池配…

HCIA复习二---7月4

路由&#xff1a; 按照路由条目&#xff0c;逻辑选址。 控制层面&#xff1a;路由条目的加表&#xff1a;AD metric&#xff08;华为 priority cost&#xff09;&#xff1b; 数据层面&#xff1a;按照路由条目转发数据包---与操作---最长匹配---递归查找&#xff1b; 静态…

第四十三周周报

学习目标&#xff1a; latent-diffusion 代码 学习时间&#xff1a; 2023.06.17 - 2023.06.30 学习产出&#xff1a; 一、代码 1、前置知识&#xff1a;PyTorch Lightning执行顺序 执行顺序&#xff1a; trainer.fit(model)&#xff1a;开始训练模型。 prepare_data()&a…

教你如何将纬地数据与实景三维模型进行叠加

概述&#xff1a; 纬地是公路设计的常用软件&#xff0c;在国内的普及率很高。传统的纬地数据文件以二维线条形式呈现在CAD中。本文提出了一种新思路、新方法&#xff0c;即将纬地的设计成果与无人机航拍的高精度倾斜摄影模型叠加在一起&#xff0c;辅助设计方案复核。 ​纬地…

SpringBoot第19讲:SpringBoot 如何保证接口幂等

SpringBoot第19讲&#xff1a;SpringBoot 如何保证接口幂等 在以SpringBoot开发Restful接口时&#xff0c;如何防止接口的重复提交呢&#xff1f; 本文是SpringBoot第19讲&#xff0c;主要介绍接口幂等相关的知识点&#xff0c;并实践常见基于Token实现接口幂等。 文章目录 Spr…

培训报名小程序实战开发

目录 1 需求描述2 原型绘制2.1 首页2.2 报名列表页2.3 报名页2.4 支付页面2.5 支付成功页面2.6 我的页面2.7 我的报名页面2.8 报名详情页面 3 数据源设计4 数据源开发5 创建模型应用6 录入测试数据7 创建自定义应用8 创建页面总结 经常有人问&#xff0c;低代码学习容易么&…

c语言进阶-枚举、联合(共用体)

枚举 枚举项也有值属性 修改枚举项值属性 枚举的优点 define的实现过程 实际在预处理已经完成了M - 100 的替换&#xff0c;实际执行是int m 100&#xff1b; enum调试的时候更方便&#xff0c;代码变化过程都可以看到。 联合&#xff08;共用体&#xff09; 打印出来的三个…