<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约束:明确抛出异常时行为

相关推荐
寻寻觅觅☆8 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
fpcc8 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
m0_607076608 小时前
CSS3 转换,快手前端面试经验,隔壁都馋哭了
前端·面试·css3
偷吃的耗子8 小时前
【CNN算法理解】:三、AlexNet 训练模块(附代码)
深度学习·算法·cnn
今天只学一颗糖8 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
NEXT069 小时前
二叉搜索树(BST)
前端·数据结构·面试
testpassportcn9 小时前
AWS DOP-C02 認證完整解析|AWS DevOps Engineer Professional 考試
网络·学习·改行学it
化学在逃硬闯CS9 小时前
Leetcode1382. 将二叉搜索树变平衡
数据结构·算法
NEXT069 小时前
JavaScript进阶:深度剖析函数柯里化及其在面试中的底层逻辑
前端·javascript·面试
ceclar1239 小时前
C++使用format
开发语言·c++·算法