變動性算法源代碼分析與使用示例(copy_backward、 transform、 replace_copy_if 等)

首先回顧前面的文章,我們把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++編程規范

轉載于:https://www.cnblogs.com/alantu2018/p/8471423.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/278392.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/278392.shtml
英文地址,請注明出處:http://en.pswp.cn/news/278392.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉]QDir類及其用法總結

直接給出原文鏈接&#xff1a;QDir類及其用法總結 轉載于:https://www.cnblogs.com/rainbow70626/p/10330643.html

如何在Outlook中的電子郵件上顯示快速操作按鈕

There are probably actions you regularly perform in Outlook, such as deleting, archiving, and marking things as read. Here’s how to use Quick Action buttons to add one-click options that appear over every email to perform each action. 您可能會在Outlook中定…

c++讀取和寫入TXT文件的整理

c讀取和寫入TXT文件的整理 #include "stdafx.h" #include <iostream> //無論讀寫都要包含<fstream>頭文件 #include <fstream> #include <iomanip> using namespace std;int main() {//ifstream從文件流向內存的ifstream表示文件輸入流…

使用RestTemplate時報錯java.lang.IllegalStateException: No instances available for 127.0.0.1

我在RestTemplate的配置類里使用了 LoadBalancedComponentpublic class RestTemplateConfig { Bean LoadBalanced public RestTemplate restTemplate(){ return new RestTemplate(); }}或者 再調用Autowiredprivate RestTemplate restTemplate;必須使用應用名作為代替ip:端口&a…

sh變量特性(3)默認特性

變量說明$0當前腳本的文件名$n傳遞給腳本或函數的參數&#xff0c;n是數字&#xff0c;第n個參數$#傳遞給腳本或函數的參數個數$*傳遞給腳本或函數的所有參數$傳遞給腳本或函數的所有參數。被””包含時&#xff0c;與$*稍有不同$?上個命令的退出狀態&#xff0c;或函數返回值…

zune linux_更新您的Zune Player軟件

zune linuxKeeping your computer and software up to date is very important in keeping everything running smooth and secure. It’s also important to keep your geeky gadgets updated as well. Here we take a look at updating a Zune HD. 保持計算機和軟件的最新狀態…

繼承的幾種方式

1.借助構造函數實現繼承 function Parent() { this.name parent } Parent.prototype.say function () { // 不能被繼承 this.say function() { console.log(hello this.name) } } function Child() { Parent.call(this) this.type child } console.log(new Child) // 沒有參…

寫一個簡單的 django_post demo

1.新建一個django工程&#xff0c;其路由為下圖 2.要做的是一個 簡單的登錄請求&#xff0c;以表單形式提交&#xff0c;html 部分代碼如下 這里注意action指向的是路由的地址&#xff0c;index1后的views.login部分代碼如下 這段代碼指的是&#xff0c;如果login接收到的請求是…

日志收集

2019獨角獸企業重金招聘Python工程師標準>>> ELK (ElasticSearch、Logstash、Kibana)&#xff1a; https://my.oschina.net/itblog/blog/547250 轉載于:https://my.oschina.net/zfscofield/blog/1625703

autocopy2u_借助AutoCopy簡化Firefox中的文本復制和粘貼

autocopy2uLooking for an easy way to speed up copying and pasting in Firefox? Now you can reduce the amount of work that you have to do by half with AutoCopy. 是否在尋找一種簡便的方法來加快Firefox中的復制和粘貼&#xff1f; 現在&#xff0c;您可以使用自動復…

virtualenv模塊使用

開發多個應用&#xff1a; 如A需要jinja2.7開發&#xff1b;如B需要jinja2.6開發。或者C需要Python2.7開發&#xff0c;D需要Python3.5開發 那么解決上述問題就需要使用virtualenv這個模塊&#xff1a; 它的作用是&#xff1a;創建“隔離”環境&#xff0c;使項目擁有獨立的Pyt…

僵尸進程處理方式

Linux服務器上&#xff0c;多少會出現一些僵尸進程&#xff0c;下面介紹如何快速尋找和消滅這些僵尸進程的方法 首先&#xff0c;我們可以用top命令來查看服務器當前是否有僵尸進程&#xff0c;在下圖中可以看到僵尸進程數的提示&#xff0c;如果數字大于0&#xff0c;那么意味…

chromebook刷機_如何查看Chromebook的停產日期

chromebook刷機Google谷歌There comes a time in your Chromebook’s life when it no longer receives updates from Google. It’s inevitable and could be a lot sooner than you think. Here’s how to see your Chromebook’s scheduled end-of-life date. Chromebook一生…

C#將unix時間戳轉換成.net的DateTime類型的代碼

下面的內容是關于C#將unix時間戳轉換成.net的DateTime類型的內容。 DateTime epoch new DateTime(1970,1,1,0,0,0,0, DateTimeKind.Utc);DateTime myDate epoch.AddSeconds(1258598728).toLocalTime(); 轉載于:https://www.cnblogs.com/odsxe/p/10338494.html

【活動】AI人工智能技術沙龍 |杭州站

AI人工智能技術沙龍 |杭州站將于2018年3月3號在浙江杭州市文一西路1818-2號中國&#xff08;杭州&#xff09;人工智能小鎮舉辦由袋鼠云、七牛云及“因特鏈”社區的老師為大家帶來AI純技術干貨分享另有區塊鏈和AI人工智能技術融合技術主題1活動安排時間&#xff1a;2018年3月3號…

如何在Google文檔中的圖片周圍換行

If you want to insert an image or object into a document, it’s relatively simple. However, positioning and getting them to stay where you want can be frustrating. The wrap text feature in Google Docs makes all of this more manageable. 如果要將圖像或對象插…

mysql的left函數

1、LEFT()函數是一個字符串函數&#xff0c;它返回具有指定長度的字符串的左邊部分。 LEFT(Str,length); 接收兩個參數&#xff1a; str&#xff1a;一個字符串&#xff1b; length&#xff1a;想要截取的長度&#xff0c;是一個正整數&#xff1b; 2、示例&#xff1a; SELECT…

如何在Linux上使用history命令

Fatmawati Achmad Zaenuri/ShutterstockFatmawati Achmad Zaenuri / ShutterstockLinux’s shell saves a history of the commands you run, and you can search it to repeat commands you’ve run in the past. Once you understand the Linux history command and how to u…

mysql導入sqlserver數據庫表

原文&#xff1a;https://zhidao.baidu.com/question/1114325744502691499.html 在Navicat for MySQL 管理器中&#xff0c;創建目標數據庫(注意&#xff1a;因為是點對點的數據導入&#xff0c;要求sql server 中要導出的數據庫名稱和要導入到Mysql 中的數據庫的名字相同)點擊…

AppleScript

AppleScript 后綴名scpt do shell script "shell腳本"轉載于:https://www.cnblogs.com/yangwenhuan/p/10338580.html