变动性算法源代码分析与使用示例(copy_backward、 transform、 replace_copy_if 等)
首先回顾前面的文章,我们把for_each 归类为非变动性算法,实际上它也可以算是变动性算法,取决于传入的第三个参数,即函数
指针。如果在函数内对容器元素做了修改,那么就属于变动性算法。
变动性算法源代码分析与使用示例:
一、copy、copy_backward
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
// TEMPLATE FUNCTION copy
template<class _InIt, class _OutIt, class _InOutItCat> inline _OutIt __CLRCALL_OR_CDECL _Copy_opt(_InIt _First, _InIt _Last, _OutIt _Dest, _InOutItCat, _Nonscalar_ptr_iterator_tag, _Range_checked_iterator_tag) { // copy [_First, _Last) to [_Dest, ...), arbitrary iterators _DEBUG_RANGE(_First, _Last); for (; _First != _Last; ++_Dest, ++_First) *_Dest = *_First; return (_Dest); } template<class _InIt, class _OutIt> // TEMPLATE FUNCTION copy_backward template < class _BidIt1, |
for (; _First != _Last; ++_Dest, ++_First)
*_Dest = *_First;
copy_backward 调用了_Copy_backward_opt,与copy 不同的是实现反向拷贝,即从尾端开始拷贝,所以是递减迭代器。
while (_First != _Last)
*--_Dest = *--_Last;
示例代码1:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#include <iostream>
#include <vector> #include <list> #include <algorithm> using namespace std; void print_element(int n) void add_3(int &n) int main(void) for_each(v.begin(), v.end(), print_element); for_each(v.begin(), v.end(), add_3); for_each(v.begin(), v.end(), print_element); for_each(l.begin(), l.end(), print_element); copy(v.begin(), v.end(), l.begin()); copy_backward(v.begin(), v.end(), l.end()); return 0; |
二、transfrom
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
// TEMPLATE FUNCTION transform WITH UNARY OP
template<class _InIt, class _OutIt, class _Fn1, class _InOutItCat> inline _OutIt _Transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func, _InOutItCat, _Range_checked_iterator_tag) { // transform [_First, _Last) with _Func _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Dest); _DEBUG_POINTER(_Func); for (; _First != _Last; ++_First, ++_Dest) *_Dest = _Func(*_First); return (_Dest); } template<class _InIt, class _OutIt, class _Fn1> // TEMPLATE FUNCTION transform WITH BINARY OP template<class _InIt1, class _InIt2, class _OutIt, class _Fn2, class _InOutItCat> template<class _InIt1, class _InIt2, class _OutIt, class _Fn2> |
实际上transfrom 重载了两个版本,一个是四个参数的,即将前两个参数指定区间内的元素执行某种操作(函数内)后拷贝到第三个
参数指示的区间上。而另一个版本是五个参数的,即将两个区间的对应元素进行某种操作后拷贝到第三个区间上去。核心的代码区
别在于下面两行:
*_Dest = _Func(*_First);
*_Dest = _Func(*_First1, *_First2);
示例代码2:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#include <iostream>
#include <vector> #include <list> #include <algorithm> using namespace std; void print_element(int n) int fun(int a) int fun2(int a, int b) int main(void) list<int> l(5); transform(v.begin(), v.end(), l.begin(), fun); transform(v.begin(), v.begin() + 2, v.begin() + 3, ll.begin(), fun2); return 0; |
输出为 :
2 4 6 8 10
5 7
三、replace、replace_copy、replace_copy_if
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
// TEMPLATE FUNCTION replace
template < class _FwdIt, class _Ty > inline void _Replace(_FwdIt _First, _FwdIt _Last, const _Ty &_Oldval, const _Ty &_Newval) { // replace each matching _Oldval with _Newval _DEBUG_RANGE(_First, _Last); for (; _First != _Last; ++_First) if (*_First == _Oldval) *_First = _Newval; } template < class _FwdIt, // TEMPLATE FUNCTION replace_copy template < class _InIt, // TEMPLATE FUNCTION replace_copy_if template < class _InIt, |
if (*_First == _Oldval)
*_First = _Newval;
replace_copy 带5个参数,先判断前两个参数指示区间的元素是否是_Oldval,若是则替换成_Newval 赋值到第三个参数指示的区间上,否则直接赋值
*_Dest = *_First == _Oldval ? _Newval : *_First;
replace_copy_if 带5个参数,在每个元素拷贝时先判断是否满足条件(函数返回为真),满足则替换成_Val,否则保持不变。
*_Dest = _Pred(*_First) ? _Val : *_First;
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#include <iostream>
#include <vector> #include <list> #include <algorithm> using namespace std; void print_element(int n) bool fun(int a) int main(void) replace(v.begin(), v.end(), 3, 13); replace_copy(v.begin(), v.end(), l.begin(), 13, 3); for_each(l.begin(), l.end(), print_element); replace_copy_if(v.begin(), v.end(), l.begin(), fun, 0); return 0; |
输出为:
1 2 13 4 13
1 2 13 4 13
1 2 3 4 3
0 0 13 0 13
参考:
C++ primer 第四版
Effective C++ 3rd
C++编程规范
变动性算法源代码分析与使用示例(copy_backward、 transform、 replace_copy_if 等)的更多相关文章
- 非变动性算法源代码分析与使用示例( for_each、min_element 、find_if、search 等)
非变动性算法代码分析与示例: 一.for_each C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // TEMPLATE FUNCTION for_eac ...
- 从零开始学C++之STL(七):剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)
一.移除性算法 (remove) C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...
- 剩下5种算法代码分析与使用示例(remove 、rotate 、sort、lower_bound、accumulate)
一.移除性算法 (remove) C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 ...
- SURF算法源代码OPENSURF分析
SURF算法源代码分析 平台:win x64 + VS2015专业版 +opencv2.4.11 配置类似参考OPENSIFT,参考我的另一篇博客:https://www.cnblogs.com/Al ...
- STL源代码分析——STL算法merge合并算法
前言 因为在前文的<STL算法剖析>中.源代码剖析许多.不方便学习.也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的merge合并算法. ...
- STL源代码分析——STL算法sort排序算法
前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...
- STL源代码分析——STL算法remove删除算法
前言 因为在前文的<STL算法剖析>中,源代码剖析许多.不方便学习,也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的remove删除算法. ...
- OpenStack_Swift源代码分析——Ring的rebalance算法源代码具体分析
1 Command类中的rebalnace方法 在上篇文章中解说了,创建Ring已经为Ring加入设备.在加入设备后须要对Ring进行平衡,平衡 swift-ring-builder object.b ...
- K-近邻算法的Python实现 : 源代码分析
网上介绍K-近邻算法的样例非常多.其Python实现版本号基本都是来自于机器学习的入门书籍<机器学习实战>,尽管K-近邻算法本身非常easy,但非常多刚開始学习的人对其Python版本号的 ...
随机推荐
- HDU 4585 Shaolin(水题,STL)
Shaolin Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Total Sub ...
- Known BREAKING CHANGES from NH3.3.3.GA to 4.0.0
Build 4.0.0.Alpha1 ============================= ** Known BREAKING CHANGES from NH3.3.3.GA to 4.0. ...
- GB2312简体中文编码表
GB2312简体中文编码表 code +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F A1A0 . . · ˉ ˇ ¨ " 々 — - | … ...
- Linux操作系统的种种集成开发环境
Linux操作系统的种种集成开发环境 随着Linux的逐渐兴起,已经有为数众多的程序在上面驰骋了,许多开发环境(Development Environment)也应运而生.好的开发环境一定是集成了编辑 ...
- FAQ:领域服务和应用服务的职责是什么?
问答部分 问: 领域服务的职责是什么? 答: 夸聚合实例业务逻辑. 没办法合理放到实体中的其它业务逻辑. 问: 领域服务的设计原则是什么? 答: 用来组织业务逻辑. 面向业务逻辑. 细粒度. 内部视图 ...
- pytest文档5-fixture之conftest.py
前言 前面一篇讲到用例加setup和teardown可以实现在测试用例之前或之后加入一些操作,但这种是整个脚本全局生效的,如果我想实现以下场景: 用例1需要先登录,用例2不需要登录,用例3需要先登录. ...
- python的异常机制使用技巧
1.当你开发的接口被其他应用调用时,响应要及时,但是有些要触发的操作很耗时间. 比如下面需要通过被调用触发的函数create_job_1().但是这个函数执行会比较消耗时间 2.于是,我们可以利用异常 ...
- Spark源码分析:多种部署方式之间的区别与联系(转)
原文链接:Spark源码分析:多种部署方式之间的区别与联系(1) 从官方的文档我们可以知道,Spark的部署方式有很多种:local.Standalone.Mesos.YARN.....不同部署方式的 ...
- iOS:本地数据库sqlite的介绍
一.数据库的概念: 1..什么是数据库 SQL Server 2010.Oracle.MySQL 关系数据库 NoSQL数据库-非关系型数据库 数据库主要由表组成 表由字段组成 数据 就是表中的记 ...
- 数学图形(2.14)Spherical helix曲线
从http://mathworld.wolfram.com/SphericalHelix.html上找到如下一些关于该曲线的说明,不过似乎他的公式和我的脚本完全是两个东西.. The tangent ...