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

相关推荐
dialect_6 小时前
KMP算法
开发语言·c++·算法
reikocao6 小时前
卡尔曼滤波的动态机制:P如何改变融合权重
算法
漂流瓶jz7 小时前
UVA-1612 猜名次 题解答案代码 算法竞赛入门经典第二版
数据结构·算法·题解·排序·aoapc·算法竞赛入门经典
夕除7 小时前
Redis 过期策略
redis·笔记·面试
吞下星星的少年·-·7 小时前
Div.2 CF 1130B题(构造,贪心)
算法·贪心·构造
ShineWinsu8 小时前
对于Qt:QRadioButton常见属性以及QButtonGroup的解析
数据库·c++·qt·microsoft·gui·qradiobutton·qbuttongroup
傲世仙尊8 小时前
多态-虚表才活到运行期符号表早已消失
c++
chenbingjie_c8 小时前
C++ 多态完全指南:从虚函数重写到虚函数表原理
开发语言·c++
是main不是漫8 小时前
【双指针——移动零】数组划分类题目的入门基石
c++·算法
Nuanyt8 小时前
Agent 学习笔记(下篇三):上线工程、进阶选择与操作界面(Stage 7 / 7.5 / 8 + 延伸路线)
笔记·python·学习·memory·aiagent·harness