C++ primer摘要(8)---泛型算法

泛型算法

概述

  • 使用標(biāo)準(zhǔn)庫(kù)算法find查找vector中的特定元素
int val = 42;
auto result = find(vec.cbegin(),vec.cend(),val);
cout << (result == vec.cend() ? "not present" : "presend") << endl;
  • 傳遞給find的前兩個(gè)參數(shù)是表示元素范圍的迭代器效拭,第三個(gè)參數(shù)是要尋找比對(duì)的值输吏,如果范圍中無(wú)匹配元素犬耻,則find返回第二個(gè)參數(shù)表示失敗
  • find操作的是迭代器煎谍,所以可以用find在任何容器中查找值
  • 可以用find在數(shù)組中擦護(hù)照值
int ia[] = {1,1,5,9,56,847,56};
int val = 83;
int * result = find(begin(ia),end(ia),val)
  • 迭代器令算法不依賴于容器坊萝,但算法依賴于元素類(lèi)型的操作
  • 算法用于不會(huì)執(zhí)行容器的操作
- [x] 泛型算法本身不會(huì)執(zhí)行容器的操作苛预,它們只會(huì)運(yùn)行在迭代器之上句狼,執(zhí)行迭代器的操作
- [x] 算法永遠(yuǎn)不會(huì)改變底層容器的大小,算法可能改變?nèi)萜髦斜4娴脑氐闹等饶常部赡茉谌萜鲀?nèi)移動(dòng)元素腻菇,但他永遠(yuǎn)不會(huì)直接添加或刪除元素
- [x] 標(biāo)準(zhǔn)庫(kù)定義了一類(lèi)特殊的迭代器,成為`插入器`昔馋,當(dāng)給這類(lèi)迭代器賦值時(shí)筹吐,它們會(huì)在底層的容器上執(zhí)行插入操作,因此秘遏,當(dāng)一個(gè)算法操作這樣的迭代器時(shí)丘薛,迭代器可以完成向容器添加元素的效果,但算法自身永遠(yuǎn)不會(huì)做這樣的操作

泛型算法

  • 除了少數(shù)例外邦危,標(biāo)準(zhǔn)庫(kù)算法都對(duì)一個(gè)范圍內(nèi)的元素進(jìn)行操作
  • 理解算法的最基本的方法就是了解它們是否讀取元素洋侨、改變?cè)鼗蛘咧嘏旁仨樞?/li>
只讀算法
  • find、accumulate以及equal函數(shù)接受三個(gè)參數(shù)
  • accumulate定義在頭文件'numeric'中倦蚪,它的前兩個(gè)參數(shù)指出了需要求和的元素的范圍希坚,第三個(gè)參數(shù)是和的初始值
int sum = accumulate(vec.cbegin(),vec.cend(),0);       //對(duì)vec中的元素求和,和的初始值是0
string sum = accumulate(v.cbegin(),v.cend(),"");
  • accumulate的第三個(gè)參數(shù)的類(lèi)型決定了函數(shù)中使用哪個(gè)加法運(yùn)算符以及返回值的類(lèi)型
  • 對(duì)于只讀取而不改變?cè)氐乃惴昵遥詈檬褂胏begin()和cend()
  • equal是操作兩個(gè)序列的算法
- [x] equal用于確定兩個(gè)序列是否保存相同的值裁僧,它將第一個(gè)序列中的每個(gè)元素與第二序列中的對(duì)應(yīng)元素進(jìn)行比較,如果所有對(duì)應(yīng)元素都相等滩报,則返回true锅知,否則返回false
- [x] 此算法接受三個(gè)迭代器,前兩個(gè)表示第一個(gè)序列中的元素范圍脓钾,第三個(gè)表示第二個(gè)序列的首元素
equal(roster1.cbegin(),roster1.cend(),roster2.cbegin());       //roster2中的元素?cái)?shù)目至少應(yīng)該與roster1一樣多
  • equal基于一個(gè)非常重要的假設(shè)售睹,它假定第二個(gè)序列至少與第一個(gè)序列一樣長(zhǎng)
  • 那些只接受一個(gè)單一迭代器來(lái)表示第二個(gè)序列的算法,都假定第二個(gè)序列至少與第一個(gè)序列一樣長(zhǎng)
寫(xiě)容器元素的算法
  • 算法fill接受一對(duì)迭代器表示一個(gè)范圍可训,還接受一個(gè)值作為第三個(gè)參數(shù)昌妹,fill將給定的這個(gè)值賦予輸入序列中的每個(gè)元素
fill(vec.begin(),vec.end(),0);  //將每個(gè)元素重置為0
  • 算法不檢查寫(xiě)操作
  • 向目的位置迭代器寫(xiě)入數(shù)據(jù)的算法假定目的位置足夠大捶枢,能容納要寫(xiě)入的元素
  • copy算法
- [x] 此算法接受三個(gè)迭代器,前兩個(gè)表示一個(gè)輸入范圍飞崖,第三個(gè)表示目的序列的起始位置
int a1[] = {0,1,2,3,4,5,6,7,8,9};
int a2[sizeof(a1)/sizeof(*a1)];         //a1和a2大小一樣
auto ret = copy(begin(a1),end(a1),a2);     //把a(bǔ)1的內(nèi)容拷貝給a2
  • replace算法
- [x] 讀入一個(gè)序列烂叔,并將其中所有等于給定值的元素都改為另一個(gè)值
- [x] 此算法接受四個(gè)參數(shù):前兩個(gè)是迭代器,表示輸入序列固歪,后兩個(gè)一個(gè)是要搜索的值蒜鸡,另一個(gè)是新值
- [x] 它將所有等于第一個(gè)值的元素替代為第二個(gè)值
replace(list.begin(),list.end(),0,42);
  • 如果需要真正的刪除無(wú)用元素,必須使用容器操作牢裳,例如erase

定制操作

lambda表達(dá)式
  • 一個(gè)lambda表達(dá)式表示一個(gè)可調(diào)用的代碼單元逢防,我們可以將其裂解為一個(gè)未命名的內(nèi)聯(lián)函數(shù)
[capture](parameter list)->return type {function body}
  • lambda表達(dá)式必須使用尾置返回
  • lambda表達(dá)式可以忽略參數(shù)列表(parameter list)和返回類(lèi)型(return type),但必須永遠(yuǎn)包含捕獲列表(capture)和函數(shù)體(function body)
  • 如果lambda的函數(shù)體包含任何單一return語(yǔ)句之外的內(nèi)容蒲讯,且未指定返回類(lèi)型忘朝,則返回void
  • 一共lambda只有在其捕獲列表中捕獲一共它所在函數(shù)中的局部變量,才能在函數(shù)體中使用該變量
  • 捕獲列表只用于局部非static變量判帮,lambda可以直接使用局部static變量和它所在函數(shù)之外聲明的名字
  • 盡量保持lambda的變量捕獲簡(jiǎn)單化

迭代器

  • 除了為每個(gè)容器定義的迭代器之外局嘁,標(biāo)準(zhǔn)庫(kù)在頭文件iterator中還定義了額外幾種迭代器
- [x] **插入迭代器**:這些迭代器被綁定到一個(gè)容器上,可以用來(lái)向容器插入元素
    - **back_inserter**
    - **front_inserter**
    - inserter
    - 只有在容器支持push_front的情況下晦墙,我們才可以使用front_inserter,類(lèi)似悦昵,只有在容器支持push_back的情況下,才能使用back_inserter
- [x] **流迭代器**:這些迭代器被綁定到輸入或輸出流上偎痛,可用來(lái)遍歷所關(guān)聯(lián)的IO流
    - **istream_iterator**讀取輸入流
    - **ostream_iterator**向一個(gè)輸出流寫(xiě)數(shù)據(jù)
- [x] **反向迭代器**:這些迭代器向后而不是向前移動(dòng)(在容器中從尾元素向首元素反向移動(dòng))旱捧,除了forward_list之外的標(biāo)準(zhǔn)庫(kù)容器都有反向迭代器
    - 對(duì)于反向迭代器独郎,遞增或遞減操作的含義會(huì)反過(guò)來(lái)
    - **rbegin\rend\crbegin\crend**
- [x] **移動(dòng)迭代器**:這些專(zhuān)用的迭代器不是拷貝其中的元素踩麦,而是移動(dòng)它們

泛型算法結(jié)構(gòu)

算法形參模式
  • 大多數(shù)算法具有如下四種形式之一:
alg(beg,end,other args);
alg(beg,end,dest,other args);
alg(beg,end,beg2,other args);
alg(beg,end,beg2,end2,other args);
  • 接受單個(gè)目標(biāo)迭代器的算法家棟目標(biāo)空間足夠容納寫(xiě)入的數(shù)據(jù)
  • 接受第二個(gè)輸入序列的算法假定從beg2開(kāi)始的序列與beg和end所表示的范圍至少一樣大

特定容器算法(鏈表類(lèi)型算法)

  • 對(duì)于list和forward_list,應(yīng)該優(yōu)先使用成員函數(shù)版本的算法而不是通用算法
  • 多數(shù)鏈表特有的算法都與其通用版本相似氓癌,但不完全相同谓谦,鏈表特有版本與通用版本間的一個(gè)至關(guān)重要的區(qū)別是鏈表版本會(huì)改變底層的容器
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市贪婉,隨后出現(xiàn)的幾起案子反粥,更是在濱河造成了極大的恐慌,老刑警劉巖疲迂,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件才顿,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡尤蒿,警方通過(guò)查閱死者的電腦和手機(jī)郑气,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)腰池,“玉大人尾组,你說(shuō)我怎么就攤上這事忙芒。” “怎么了讳侨?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵呵萨,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我跨跨,道長(zhǎng)潮峦,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任勇婴,我火速辦了婚禮跑杭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘咆耿。我一直安慰自己德谅,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布萨螺。 她就那樣靜靜地躺著窄做,像睡著了一般。 火紅的嫁衣襯著肌膚如雪慰技。 梳的紋絲不亂的頭發(fā)上椭盏,一...
    開(kāi)封第一講書(shū)人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音吻商,去河邊找鬼掏颊。 笑死,一個(gè)胖子當(dāng)著我的面吹牛艾帐,可吹牛的內(nèi)容都是我干的乌叶。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼柒爸,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼准浴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起捎稚,我...
    開(kāi)封第一講書(shū)人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤乐横,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后今野,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體葡公,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年条霜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了催什。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛔外,死狀恐怖蛆楞,靈堂內(nèi)的尸體忽然破棺而出溯乒,到底是詐尸還是另有隱情,我是刑警寧澤豹爹,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布裆悄,位于F島的核電站,受9級(jí)特大地震影響臂聋,放射性物質(zhì)發(fā)生泄漏光稼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一孩等、第九天 我趴在偏房一處隱蔽的房頂上張望艾君。 院中可真熱鬧,春花似錦肄方、人聲如沸冰垄。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)虹茶。三九已至,卻和暖如春隅要,著一層夾襖步出監(jiān)牢的瞬間蝴罪,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工步清, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留要门,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓廓啊,卻偏偏與公主長(zhǎng)得像欢搜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崖瞭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355