<algorithm>文件中copy、copy_n 、copy_if 、copy_backward算法学习

学习内容

本节学习内部的算法copy、copy_n 、copy_if 、copy_backward

copy(C++98引入)

功能: 将原序列范围内的所有元素,按照顺序拷贝到目标序列

原型:

template < class InputIt , class OutputIt >

OutputIt copy ( InputIt first , InputIt last , OutputIt d_first);

参数解析:

first / last : 原序列的起始/终止迭代器,拷贝范围为 [first , last)

d_first : 目标序列的起始迭代器,拷贝从该位置开始

返回值:目标序列中最后一个拷贝元素的下一个迭代器(end())

用法:

cpp 复制代码
vector<int> src = { 1 ,2, 3, 4 ,5 };
vector<int> dst(src.size());
//返回it的end()
auto it = copy ( src.begin(),src.end(),dst.begin());

copy_n (C++11引入)

功能:从原序列的起始位置first开始,拷贝N个元素到目标序列(从d_first开始),无需指定原序列结束位置

原型:

template <class InputIt , class Size , class OutputIt>

OutputIt copy_n( InputIt first , Size n ,OutputIt d_first );

参数解析:

first: 原序列的起始迭代器,拷贝范围为 [first ,first + n ]

n : 需要拷贝的元素的数量

d_first : 目标序列的起始迭代器,拷贝从该位置开始

返回值:目标序列中最后一个拷贝元素的下一个迭代器(end())

用法:

cpp 复制代码
vector<int> src = { 1 ,2, 3, 4 ,5 };
vector<int> dst(3);

auto it = copy_n( src.begin() , 3 , dst.begin());

copy_if (C++11引入)

功能:遍历原序列[ first , last ),将满足自定义条件的元素,按从左到右顺序拷贝到目标序列(从d_first开始),带筛选逻辑的拷贝

原型:

template < class InputIt , class OutputIt , class UnaryPredicate>

OutputIt copy ( InputIt first , InputIt last , OutputIt d_first , UnaryPredicate p);

参数解析:

first / last : 原序列的起始/终止迭代器,拷贝范围为 [first , last)

d_first : 目标序列的起始迭代器,拷贝从该位置开始

p : 单参函数(函数指针,函数对象,lambda),接受一个原序列元素,返回bool

返回值:目标序列中最后一个拷贝元素的下一个迭代器(end())

用法:

cpp 复制代码
vector<int> src = { 1 ,2, 3, 4 ,5 };
vector<int> dst(3);
auto it = copy_if( src.begin() , src.end() , dst.begin() , [](int ele) { return ele > 2 ; };

copy_backward(C++98引入)

功能:将原序列[ first ,last )范围内所有元素,按照逆序( last -1 , first )拷贝到目标序列的后向位置 ( d_last -1开始),解决原/目标序列重叠时拷贝覆盖问题

原型:

template < class BidirectionalIt1 , class BidirectionalIt2 >

BidirectionalIt2 copy_backward( BidirectionalIt1 first , BidirectionalIt1 last , BirectionalIt2 d_last );

参数解析:

first / last : 原序列的起始/终止迭代器,拷贝范围为 [first , last)(要求为双向迭代器)

d_last : 目标序列的终止迭代器,拷贝从 d_last-1 开始 (要求为双向迭代器)

返回值:目标序列中第一个拷贝元素的迭代器(begin())

用法:

cpp 复制代码
//覆盖问题,操作同一个队列
vector<int> src = { 1 ,2, 3, 4 ,5 ,0,0};
auto it = copy_backward( src.begin(),src.end(), src.end());

vector<int> vec = { 6, 6, 8};
vector<int> dst(3);
auto iter = copy_backward( vec.begin(),vec.begin()+3 , dst.end());

C++14无重大变化

C++17 并行化重载+迭代器约束强化

1、为四个算法均新增了带执行策略的重载,支持串行、并行、并行向量化三种指定方式(均在第一个参数位置)

执行策略类型:

std::execution:seq : 串行执行

std::execution::par:并行执行

std::execution::par_unseq: 并行向量化执行

适用场景: 当拷贝元素数量巨大时,使用并行可减少拷贝耗时

cpp 复制代码
//包含头文件 <execution>
vector<int> src(1000000,1);
vector<int> dst(1000000);

copy(exection::par , src.begin() , src.end() , dst.begin() );
copy_n( exection::par , src.begin(),500000, dst.begin());
copy_if( exection::par,src.begin(),src.end() ,dst.begin() , [](int x) { return x > 0 ; } );
copy_backward (exection::par , src.begin() , src.end() , dst.end());

2、迭代器约束编译器显式化

通过static_assert和迭代器特性检测,让四个算法迭代器约束从运行时未定义变成编译期显式报错

例如copy_backward只能使用双向迭代器,这样在编译期就可以检测迭代器是否为双向

3、copy_if的一元函数支持可移动类型 (接受const& / && 元素)

C++20 增加两个特性:constexpr和Concepts,实现编译期运行和迭代器的强类型约束

1、四个算法均支持constexpr重载版本,在编译期可完成拷贝

编译期执行条件:原/目标序列指向编译期可访问内存(constexpr、std::array); 元素类型为字面量 ;若为copy_if,则参数类型必须是constexpr可调用对象

constexpr array<int,4> src = { 1 ,2 ,3 ,4 };

constexpr array<int,4> dst = <>{

array<int,4> tmp = {0};

constexpr copy (src.begin() , src.end() , tmp.begin() );

return tmp;

}();

2、迭代器约束基于Concepts强类型化

四种算法原型中的 class InputIt ,class OutputIt,约束为std::input_iterator , std::output_interator等,copy_backward中双向迭代器的目标约束为std::bidirectional_iterator

3、copy_n中的n支持无符号类型大小

C++23 底层性能优化

1、连续内存迭代器特化优化:对访问随机迭代器(vector/array等)做编译期特化,直接调用内存块拷贝,替代逐元素拷贝

2、copy_backward重叠检测优化:检测若无重叠情况,自动将函数优化为copy

3、空范围拷贝:对原序列的first==last的或copy_n中n=0的情况,直接返回目标迭代器

4、copy_if中单参函数的noexcept约束:明确抛出异常时行为

相关推荐
带娃的IT创业者12 小时前
营养食谱推荐引擎:基于规则与协同过滤的混合算法
算法·规则引擎·协同过滤·健康管理·食谱推荐·营养搭配·家庭饮食
君鼎12 小时前
More Effective C++ 条款35:让自己熟悉C++标准库
c++
扶摇接北海17612 小时前
洛谷:P1307 [NOIP 2011 普及组] 数字反转
c++·算法·洛谷
Fortune7912 小时前
实时操作系统中的C++
开发语言·c++·算法
keyborad pianist12 小时前
数据结构
数据结构·学习
AI科技星12 小时前
基于v≡c光速螺旋理论的正确性证明:严格遵循科学方法论的完整路径
c语言·开发语言·人工智能·线性代数·算法·机器学习·数学建模
草莓熊Lotso12 小时前
Linux 进程信号深度解析(下):信号的保存、阻塞与捕捉
android·linux·运维·服务器·数据库·c++·性能优化
ALex_zry14 小时前
C++ ORM与数据库访问层设计:Repository模式实战
开发语言·数据库·c++
RFdragon16 小时前
分享本周所学——三维重建算法3D Gaussian Splatting(3DGS)
人工智能·线性代数·算法·机器学习·计算机视觉·矩阵·paddlepaddle
浅念-18 小时前
Linux 开发环境与工具链
linux·运维·服务器·数据结构·c++·经验分享