首先回顾前面的文章,我们把for_each 归类为非变动性算法,实际上它也可以算是变动性算法,取决于传入的第三个参数,即函数

指针。如果在函数内对容器元素做了修改,那么就属于变动性算法。

变动性算法源代码分析与使用示例:

一、copy、copy_backward

 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
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>
inline
_IF_CHK(_OutIt) __CLRCALL_OR_CDECL copy(_InIt _First, _InIt _Last, _OutIt _Dest)
{
    // copy [_First, _Last) to [_Dest, ...)
    return (_Copy_opt(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest,
                      _Iter_random(_First, _Dest), _Ptr_cat(_First, _Dest), _Range_checked_iterator_tag()));
}

// TEMPLATE FUNCTION copy_backward
template<class _BidIt1, class _BidIt2, class _InOutItCat>
inline
_BidIt2 __CLRCALL_OR_CDECL _Copy_backward_opt(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest,
        _InOutItCat, _Nonscalar_ptr_iterator_tag, _Range_checked_iterator_tag)
{
    // copy [_First, _Last) backwards to [..., _Dest), arbitrary iterators
    _DEBUG_RANGE(_First, _Last);
    while (_First != _Last)
        *--_Dest = *--_Last;
    return (_Dest);
}

template < class _BidIt1,
         class _BidIt2 > inline
_IF_CHK(_BidIt2) __CLRCALL_OR_CDECL copy_backward(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest)
{
    // copy [_First, _Last) backwards to [..., _Dest)
    return _Copy_backward_opt(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest,
                              _Iter_random(_First, _Dest), _Ptr_cat(_First, _Dest), _STD _Range_checked_iterator_tag());
}

for (; _First != _Last; ++_Dest, ++_First)

*_Dest = *_First;

copy_backward 调用了_Copy_backward_opt,与copy 不同的是实现反向拷贝,即从尾端开始拷贝,所以是递减迭代器。

while (_First != _Last)

*--_Dest = *--_Last;

示例代码1:

 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
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)
{
    cout << n << ' ';
}

void add_3(int &n)
{
    n += 3;
}

int main(void)
{
    int a[] = { 1, 2, 3, 4, 5 };
    vector<int> v(a, a + 5);
    list<int> l(15);

for_each(v.begin(), v.end(), print_element);
    cout << endl;

for_each(v.begin(), v.end(), add_3);

for_each(v.begin(), v.end(), print_element);
    cout << endl;

for_each(l.begin(), l.end(), print_element);
    cout << endl;

copy(v.begin(), v.end(), l.begin());
    for_each(l.begin(), l.end(), print_element);
    cout << endl;

copy_backward(v.begin(), v.end(), l.end());
    for_each(l.begin(), l.end(), print_element);
    cout << endl;

return 0;
}

二、transfrom

 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
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>
inline
_IF_CHK(_OutIt) transform(_InIt _First, _InIt _Last, _OutIt _Dest, _Fn1 _Func)
{
    return _Transform(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Func,
                      _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
}

// TEMPLATE FUNCTION transform WITH BINARY OP
template<class _InIt1, class _InIt2, class _OutIt, class _Fn2, class _InItCats, class _InOutItCat>
inline
_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
                  _OutIt _Dest, _Fn2 _Func,
                  _InItCats, _InOutItCat,
                  _Range_checked_iterator_tag, _Range_checked_iterator_tag)
{
    // transform [_First1, _Last1) and [_First2, _Last2) with _Func
    _DEBUG_RANGE(_First1, _Last1);
    _DEBUG_POINTER(_Dest);
    _DEBUG_POINTER(_Func);
    for (; _First1 != _Last1; ++_First1, ++_First2, ++_Dest)
        *_Dest = _Func(*_First1, *_First2);
    return (_Dest);
}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2, class _InOutItCat>
inline
_OutIt _Transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
                  _OutIt _Dest, _Fn2 _Func,
                  random_access_iterator_tag, _InOutItCat,
                  _Range_checked_iterator_tag, _Range_checked_iterator_tag)
{
    // transform [_First1, _Last1) and [_First2, _Last2) with _Func
    // for range checked iterators, this will make sure there is enough space
    _InIt2 _Last2 = _First2 + (_Last1 - _First1);
    (_Last2);
    return _Transform(_First1, _Last1, _CHECKED_BASE(_First2),
                      _Dest, _Func,
                      forward_iterator_tag(), forward_iterator_tag(),
                      _Range_checked_iterator_tag(), _Range_checked_iterator_tag());
}

template<class _InIt1, class _InIt2, class _OutIt, class _Fn2>
inline
_IF_CHK2_(_InIt2, _OutIt, _OutIt) transform(_InIt1 _First1, _InIt1 _Last1, _InIt2 _First2,
        _OutIt _Dest, _Fn2 _Func)
{
    return _Transform(_CHECKED_BASE(_First1), _CHECKED_BASE(_Last1), _First2, _Dest, _Func,
                      _Iter_random(_First1, _First2), _Iter_random(_First1, _Dest),
                      _STD _Range_checked_iterator_tag(), _STD _Range_checked_iterator_tag());
}

实际上transfrom 重载了两个版本,一个是四个参数的,即将前两个参数指定区间内的元素执行某种操作(函数内)后拷贝到第三个

参数指示的区间上。而另一个版本是五个参数的,即将两个区间的对应元素进行某种操作后拷贝到第三个区间上去。核心的代码区

别在于下面两行:

*_Dest = _Func(*_First);

*_Dest = _Func(*_First1, *_First2);

示例代码2:

 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
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)
{
    cout << n << ' ';
}

int fun(int a)
{
    return 2 * a;
}

int fun2(int a, int b)
{
    return a + b;
}

int main(void)
{
    int a[] = { 1, 2, 3, 4, 5 };
    vector<int> v(a, a + 5);

list<int> l(5);
    list<int> ll(2);

transform(v.begin(), v.end(), l.begin(), fun);
    for_each(l.begin(), l.end(), print_element);
    cout << endl;

transform(v.begin(), v.begin() + 2, v.begin() + 3, ll.begin(), fun2);
    for_each(ll.begin(), ll.end(), print_element);
    cout << endl;

return 0;
}

输出为 :

2 4 6 8 10

5 7

三、replace、replace_copy、replace_copy_if

 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
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,
         class _Ty > inline
void replace(_FwdIt _First, _FwdIt _Last,
             const _Ty &_Oldval, const _Ty &_Newval)
{
    // replace each matching _Oldval with _Newval
    _Replace(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Oldval, _Newval);
}

// TEMPLATE FUNCTION replace_copy
template<class _InIt, class _OutIt, class _Ty, class _InOutItCat>
inline
_OutIt _Replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
                     const _Ty &_Oldval, const _Ty &_Newval,
                     _InOutItCat, _Range_checked_iterator_tag)
{
    // copy replacing each matching _Oldval with _Newval
    _DEBUG_RANGE(_First, _Last);
    _DEBUG_POINTER(_Dest);
    for (; _First != _Last; ++_First, ++_Dest)
        *_Dest = *_First == _Oldval ? _Newval : *_First;
    return (_Dest);
}

template < class _InIt,
         class _OutIt,
         class _Ty > inline
_IF_CHK(_OutIt) replace_copy(_InIt _First, _InIt _Last, _OutIt _Dest,
                             const _Ty &_Oldval, const _Ty &_Newval)
{
    // copy replacing each matching _Oldval with _Newval
    return _Replace_copy(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Oldval, _Newval,
                         _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
}

// TEMPLATE FUNCTION replace_copy_if
template<class _InIt, class _OutIt, class _Pr, class _Ty, class _InOutItCat>
inline
_OutIt _Replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
                        _Pr _Pred, const _Ty &_Val, _InOutItCat, _Range_checked_iterator_tag)
{
    // copy replacing each satisfying _Pred with _Val
    _DEBUG_RANGE(_First, _Last);
    _DEBUG_POINTER(_Dest);
    _DEBUG_POINTER(_Pred);
    for (; _First != _Last; ++_First, ++_Dest)
        *_Dest = _Pred(*_First) ? _Val : *_First;
    return (_Dest);
}

template < class _InIt,
         class _OutIt,
         class _Pr,
         class _Ty > inline
_IF_CHK(_OutIt) replace_copy_if(_InIt _First, _InIt _Last, _OutIt _Dest,
                                _Pr _Pred, const _Ty &_Val)
{
    // copy replacing each satisfying _Pred with _Val
    return _Replace_copy_if(_CHECKED_BASE(_First), _CHECKED_BASE(_Last), _Dest, _Pred, _Val,
                            _Iter_random(_First, _Dest), _STD _Range_checked_iterator_tag());
}

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;

 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
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)
{
    cout << n << ' ';
}

bool fun(int a)
{
    return a < 10;
}

int main(void)
{
    int a[] = { 1, 2, 3, 4, 3 };
    vector<int> v(a, a + 5);
    list<int> l(5);

replace(v.begin(), v.end(), 3, 13);
    for_each(v.begin(), v.end(), print_element);
    cout << endl;

replace_copy(v.begin(), v.end(), l.begin(), 13, 3);
    for_each(v.begin(), v.end(), print_element);
    cout << endl;

for_each(l.begin(), l.end(), print_element);
    cout << endl;

replace_copy_if(v.begin(), v.end(), l.begin(), fun, 0);
    for_each(l.begin(), l.end(), print_element);
    cout << endl;

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 等)的更多相关文章

  1. 非变动性算法源代码分析与使用示例( 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 ...

  2. 从零开始学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 ...

  3. 剩下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 ...

  4. SURF算法源代码OPENSURF分析

    SURF算法源代码分析 平台:win x64 + VS2015专业版 +opencv2.4.11 配置类似参考OPENSIFT,参考我的另一篇博客:https://www.cnblogs.com/Al ...

  5. STL源代码分析——STL算法merge合并算法

    前言 因为在前文的<STL算法剖析>中.源代码剖析许多.不方便学习.也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的merge合并算法. ...

  6. STL源代码分析——STL算法sort排序算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多,不方便学习,也不方便以后复习.这里把这些算法进行归类,对他们单独的源代码剖析进行解说.本文介绍的STL算法中的sort排序算法,SG ...

  7. STL源代码分析——STL算法remove删除算法

    前言 因为在前文的<STL算法剖析>中,源代码剖析许多.不方便学习,也不方便以后复习,这里把这些算法进行归类.对他们单独的源代码剖析进行解说.本文介绍的STL算法中的remove删除算法. ...

  8. OpenStack_Swift源代码分析——Ring的rebalance算法源代码具体分析

    1 Command类中的rebalnace方法 在上篇文章中解说了,创建Ring已经为Ring加入设备.在加入设备后须要对Ring进行平衡,平衡 swift-ring-builder object.b ...

  9. K-近邻算法的Python实现 : 源代码分析

    网上介绍K-近邻算法的样例非常多.其Python实现版本号基本都是来自于机器学习的入门书籍<机器学习实战>,尽管K-近邻算法本身非常easy,但非常多刚開始学习的人对其Python版本号的 ...

随机推荐

  1. The method setClass(Context, Class<?>) in the type Intent is not applicable for the arguments (GameV

    在当前短信内容的activity中写            Bundle bun = new Bundle();         bun.putString("message",  ...

  2. 程序员应该知道的几个国外IT网站

    程序员应该知道的几个国外IT网站   摘要:文中总结了几个常用的国外IT网站,下面列举出来供大家学习参考: 导读:文中总结了几个常用的国外IT网站,下面列举出来供大家学习参考: 1. TheServe ...

  3. rt-80启动tomcat

    1 #!/bin/sh 2 cd /mnt/tomcat/tomcat_8082; 3 ps -ef|grep /tomcat_8082/ |awk '{print $2}'|xargs kill - ...

  4. 优化png图片的历程

    一.使用yslow一个tool  找到一个叫做smush的工具,点击就可以进入工具的页面. 然后你就能够压缩,下载压缩后的图片. 可是终于我还是没有选择这个方案.由于压缩的图片大小还是太大了,我认为还 ...

  5. ubuntu 设置静态IP GW

    网卡配置静态IP地址 编辑文件/etc/network/interfaces: sudo vi /etc/network/interfaces 并用下面的行来替换有关eth0的行:# The prim ...

  6. jquery点击回到页面顶部方法

    1.代码实例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  7. nib 加载过程分析以及对File’s Owner的理解

    nib loading的过程,这个是app文档里面有说到资源编程指南 1.  It loads the contents of the nib file and any referenced reso ...

  8. 【采集层】Kafka 与 Flume 如何选择(转)

    原文链接:[采集层]Kafka 与 Flume 如何选择 采集层 主要可以使用Flume, Kafka两种技术. Flume:Flume 是管道流方式,提供了很多的默认实现,让用户通过参数部署,及扩展 ...

  9. 数学图形(2.15)Spherical sinusoid球面正弦曲线

    这个曲线与之前的数学图形(2.7)sphere sine wave很相似.而且个人觉得从其公式上看sphere sine wave更应该叫做球面正弦曲线.当然从渲染的曲线图上看,它是非常明显的贴在球上 ...

  10. QT源码之Qt信号槽机制与事件机制的联系

    QT源码之Qt信号槽机制与事件机制的联系是本文要介绍的内容,通过解决一个问题,从中分析出的理论,先来看内容. 本文就是来解决一个问题,就是当signal和slot的连接为Qt::QueuedConne ...