STL學習筆記

STL(Standard Template Library)里有很多組成部分,但是主要有三個,容器爱榔、迭代器和算法

容器用來管理某個特定對象的集合掉冶。每一種容器都有自己的優(yōu)點和缺點真竖,在項目中根據(jù)不同的需求,使用不同的容器厌小。容器可以是數(shù)組恢共、鏈表或者類字典。

迭代器用于遍歷對象集合的元素璧亚。這些集合可以是容器或容器的子集讨韭。每一個容器類都提供了它自己的迭代器類型。

算法用來處理的元素的集合癣蟋。例如透硝,可以進行搜索、排序等操作疯搅。

STL的數(shù)據(jù)和操作是分離的濒生。數(shù)據(jù)存儲在容器里,使用算法進行操作幔欧。迭代器是這兩者之間的粘合劑罪治,讓算法與容器可以進行交互。

某種程度上礁蔗,STL的概念與面向?qū)ο缶幊痰脑瓌t相背觉义,

STL數(shù)據(jù)和算法是分離的而不是結(jié)合。STL是泛型編程的一個很好的例子浴井。容器和算法分別是任意類型和類的泛型晒骇。STL提供了更通用的組件。還可以通過使用適配器和仿函數(shù)來達到特殊要求。

容器

容器管理著一系列元素厉碟,為了滿足不同的需求喊巍,STL提供了多種類型的容器,見下圖箍鼓。

主要可以分為三大類

序列容器是有序集合崭参,其中的每個元素都有特定位置。這個位置取決于插入的時間和地點款咖,但是它跟元素的值無關(guān)何暮。STL包含5個預(yù)定義的序列容器類:array、vector铐殃、deque海洼、list和forward_list。

關(guān)聯(lián)容器是把元素的值按照某種規(guī)則排好順序的集合富腊。STL包含4個預(yù)定義的關(guān)聯(lián)容器類:set坏逢、multiset、map和multimap赘被。

無序(關(guān)聯(lián))容器是無序集合是整。主要關(guān)注一個元素是否在集合中。不論是插入的順序還是插入元素的值對元素的位置都沒有任何影響民假。STL包含4個預(yù)定義的無序容器類:unordered_set浮入、unordered_multiset、unordered_map和unordered_multimap羊异。

序列容器通常是數(shù)組或鏈表的實現(xiàn)

關(guān)聯(lián)容器通常是二叉樹的實現(xiàn)

無序容器通常是哈希表的實現(xiàn)

容器適配器

容器適配器提供順序容器的特殊接口

stack 堆棧適配器(LIFO)

queue 改寫容器來提供隊列(FIFO數(shù)據(jù)結(jié)構(gòu))

priority_queue 改寫容器來提供優(yōu)先級隊列

迭代器

根據(jù)迭代器所支持的操作事秀,一般分為下面5種。

前向迭代器只能利用遞增運算符進行前向迭代野舶。像unordered_set易迹、unordered_multiset、unordered_map和unordered_multimap這些容器都“至少”是用前向迭代器(某些情況下可以提供雙向迭代器)筒愚。

雙向迭代器是可以用遞增運算符向前迭代赴蝇,或者用遞減運算符向后迭代菩浙。像list巢掺、set、multiset劲蜻、map和multimap的迭代器都是雙向迭代器陆淀。

隨機訪問迭代器具有雙向迭代器的所有屬性。此外先嬉,他們還可以進行隨機訪問轧苫。這種迭代器本身支持運算操作,可以改變偏移量,也可以利用關(guān)系運算符(< 和 >)比較迭代器含懊。像vector身冬、deque、array和string的迭代器都是這類迭代器岔乔。

輸入迭代器能夠在迭代時讀取或處理一些值酥筝。如Input stream iterators。

輸出迭代器能夠在迭代時輸出一些值雏门。如Inserters嘿歌、和output stream iterators。

算法

STL提供了一些標準算法來處理集合元素茁影。這些算法一般提供最基本的功能宙帝,如搜索、排序募闲、復(fù)制步脓、修改和數(shù)值處理。

算法不是容器類的成員函數(shù)浩螺,而是全局函數(shù)沪编。算法可以操作不同容器類型的元素,甚至可以操作用戶自定義的容器類型年扩∫侠總之,既減少了代碼量厨幻,又增強了性能相嵌。

迭代器適配器

任何操作起來像迭代器的東西都可以當作迭代器。所以可以寫出像迭代器的一些類但又執(zhí)行不一樣的操作况脆。C++標準庫提供的一些預(yù)定義的特殊迭代器饭宾,即迭代器適配器。

一般分為四類:

Insert iterators也稱為inserters格了,用來將“賦值新值”操作轉(zhuǎn)換為“安插新值”操作看铆。通過這種迭代器,算法可以執(zhí)行安插(insert)行為而非覆蓋(overwrite)行為盛末。所有Insert迭代器都隸屬于Output迭代器類型弹惦,所以它只提供賦值(assign)新值的能力。通常算法會將數(shù)值賦值給目的迭代器悄但,如copy()算法

Stream iterators是一種迭代器配接器棠隐,可以把stream當成算法的原點和終點。更明確的說檐嚣,一個istream迭代器可以用來從input stream中讀元素助泽,而一個ostream迭代器可以用來對output stream寫入元素。Stream迭代器的一種特殊形式是所謂的stream緩沖區(qū)迭代器,用來對stream緩沖區(qū)進行直接讀取和寫入操作嗡贺。

Reverse iterators重新定義遞增運算和遞減運算隐解,使其行為正好倒置。

Move iterators很像一個底層迭代器(必須至少有一個InputIterator)诫睬。如果這個迭代器被當作輸入迭代器來用厢漩,要注意的是,值的操作是移動而不是復(fù)制岩臣。

重點介紹向量:

向量容器使用動態(tài)數(shù)組存儲溜嗜、管理對象。因為數(shù)組是一個隨機訪問數(shù)據(jù)結(jié)構(gòu)架谎,所以可以隨機訪問向量中的元素炸宵。在數(shù)組中間或是開始處插入一個元素是費時的,特別是在數(shù)組非常大的時候更是如此谷扣。然而在數(shù)組末端插入元素卻很快土全。

實現(xiàn)向量容器的類名是vector(容器是類模板)。包含vector類的頭文件名是vector会涎。所以裹匙,如果要在程序里使用向量容器,就要在程序中包含下面語句:

#include

此外末秃,在定義向量類型對象時概页,必須指定該對象的類型,因為vector類是一個類模板练慕。例如惰匙,語句:

vector intList;

將intList聲明為一個元素類型為int的向量容器對象。類似地铃将,語句:

vector stringList;將stringList聲明為一個元素類型為string的向量容器對象项鬼。

聲明向量對象

vector類包含了多個構(gòu)造函數(shù),其中包括默認構(gòu)造函數(shù)劲阎。因此绘盟,可以通過多種方式來聲明和初始化向量容器。表一描述了怎樣聲明和初始化指定類型的向量容器悯仙。

表一???? 各種聲明和初始向量容器的方法

語句作用

vector vecList;創(chuàng)建一個沒有任何元素的空向量vecList(使用默認構(gòu)造函數(shù))

vector vecList(otherVecList)創(chuàng)建一個向量vecList龄毡,并使用向量otherVecList中的元素初始化該向量。向量vecList與向量otherVecList的類型相同

vector vecLIst(size);

創(chuàng)建一個大小為size的向量vecList雁比,并使用默認構(gòu)造函數(shù)初始化該向量

vector vecList(n,elem);創(chuàng)建一個大小為n的向量vecList稚虎,該向量中所有的n個元素都初始化為elem

vector vecList(begin,end);創(chuàng)建一個向量vecList,并初始化該向量(begin,end)中的元素偎捎。即,從begin到end-1之間的所有元素

在介紹了如何聲明向量順序容器之后,讓我們開始討論如何操作向量容器中的數(shù)據(jù)茴她。首先寻拂,必須要知道下面幾種基本操作:

元素插入

元素刪除

遍歷向量容器中的元素

假設(shè)vecList是一個向量類型容器。表二給出了在vecList中插入元素和刪除元素的操作丈牢,這些操作是vector類的成員函數(shù)祭钉。表二還說明了如何使用這些操作。

表二???? 向量容器上的各種操作

語句作用

vecList.clear()從容器中刪除所有元素

vecList.erase(position)刪除由position指定的位置上的元素

vecList.erase(beg,end)刪除從beg到end-1之間的所有元素

vecList.insert(position, elem)將elem的一個拷貝插入到由position指定的位置上己沛,并返回新元素的位置

vecList.inser(position, n, elem)將elem的n個拷貝插入到由 position指定的位置上

vecList.insert(position, beg, end)將從beg到end-1之間的所有元素的拷貝插入到vecList中由position指定的位置上

vecList.push_back(elem)將elem的一個拷貝插入致List的末尾

vecList.pop_back()刪除最后元素

vecList.resize(num)將元素個數(shù)改為num慌核。如果size()增加,默認的構(gòu)造函數(shù)負責創(chuàng)建這些新元素

vecList.resize(num, elem)將元素個數(shù)改為num申尼。如果size()增加垮卓,默認的構(gòu)造函數(shù)將這些新元素初始化為elem

在向量容器中聲明迭代器

vector類包含了一個typedef iterator,這是一個public成員师幕。通過iterator粟按,可以聲明向量容器中的迭代器。例如霹粥,語句:

vector::iterator intVeciter;??????? 將intVecIter聲明為int類型的向量容器迭代器灭将。

因為iterator是一個定義在vector類中的typedef,所以必須使用容器名(vector)后控、容器元素類型和作用域符來使用iterator庙曙。

表達式:

++intVecIter

將迭代器intVecIter加1,使其指向容器中的下一個元素浩淘。表達式:*intVecIter

返回當前迭代器位置上的元素矾利。

注意,迭代器上的這些操作和指針上的相應(yīng)操作是相同的馋袜。運算符*作為單目運算符使用時男旗,稱為遞引用運算符。

下面將討論如何使用迭代器來操作向量容器中的數(shù)據(jù)。假設(shè)有下面語句:

vector intList;

vector::iterator intVecIter;

第一行中的語句將intList聲明為元素為int類型的向量容器。第二行中的語句將intVecIter聲明為元素為int類型的向量容器的迭代器涛酗。

容器與函數(shù)begin和end

所有容器都包含成員函數(shù)begin和end再层。函數(shù)begin返回容器中第一個元素的位置;函數(shù)end返回容器中最后一個元素的位置蠕嫁。這兩個函數(shù)都沒有參數(shù)。在執(zhí)行下面語句:

intVecIter = intList.begin();

迭代器intVecIter指向容器intList中第一個元素。

下面的for循環(huán)將intList中所有元素輸出互標準輸出設(shè)備上:

for (intVecIter = intList.begin(); intVecIter != intList.end();

cout<<*intVecList<<"???? ";

可以通過表三中給出的操作直接訪問向量容器中的元素稻爬。

表三 訪問向量容器中元素的操作

表達式作用

vecList.at(index)返回由index指定的位置上的元素

vecList[index]返回由index指定的位置上的元素

vecList.front()返回第一個元素 (不檢查容器是否為空)

vecList.back()返回最后一個元素(不檢查容器是否為空)

表三說明:可以按照數(shù)組的方式來處理向量中的元素(注意蜕依,在C++中桅锄,數(shù)組下標從0始琉雳。,向量容器中第一個元素的位置也是0)友瘤。

徽號類中還包含:返回容器中當前元素個數(shù)的成員函數(shù)翠肘,返回可以插入到容器中的元素的最大個數(shù)的成員函數(shù)等。表四描述其中 一些操作(假設(shè)vecCont是向量容器)辫秧。

表四 計算向量容器大小的操作

表達式作用

vecCont.capacity()返回不重新分配空間可以插入到容器vecCont中的元素的最大個數(shù)

vecCont.empty()容器vecCont為空束倍,返回true;否則盟戏,返回false

vecCont.size()返回容器vecCont中當前的個數(shù)

vecCont.max_size()返回可以插入到容器vecCont中的元素的最大個數(shù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绪妹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子柿究,更是在濱河造成了極大的恐慌邮旷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,561評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件笛求,死亡現(xiàn)場離奇詭異廊移,居然都是意外死亡,警方通過查閱死者的電腦和手機探入,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評論 3 385
  • 文/潘曉璐 我一進店門狡孔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蜂嗽,你說我怎么就攤上這事苗膝。” “怎么了植旧?”我有些...
    開封第一講書人閱讀 157,162評論 0 348
  • 文/不壞的土叔 我叫張陵辱揭,是天一觀的道長。 經(jīng)常有香客問我病附,道長问窃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,470評論 1 283
  • 正文 為了忘掉前任完沪,我火速辦了婚禮域庇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘覆积。我一直安慰自己听皿,他們只是感情好,可當我...
    茶點故事閱讀 65,550評論 6 385
  • 文/花漫 我一把揭開白布宽档。 她就那樣靜靜地躺著尉姨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吗冤。 梳的紋絲不亂的頭發(fā)上又厉,一...
    開封第一講書人閱讀 49,806評論 1 290
  • 那天九府,我揣著相機與錄音,去河邊找鬼馋没。 笑死昔逗,一個胖子當著我的面吹牛降传,可吹牛的內(nèi)容都是我干的篷朵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼婆排,長吁一口氣:“原來是場噩夢啊……” “哼声旺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起段只,我...
    開封第一講書人閱讀 37,712評論 0 266
  • 序言:老撾萬榮一對情侶失蹤腮猖,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赞枕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體澈缺,經(jīng)...
    沈念sama閱讀 44,166評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,510評論 2 327
  • 正文 我和宋清朗相戀三年炕婶,在試婚紗的時候發(fā)現(xiàn)自己被綠了姐赡。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,643評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡柠掂,死狀恐怖项滑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情涯贞,我是刑警寧澤枪狂,帶...
    沈念sama閱讀 34,306評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站宋渔,受9級特大地震影響州疾,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜皇拣,卻給世界環(huán)境...
    茶點故事閱讀 39,930評論 3 313
  • 文/蒙蒙 一严蓖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧审磁,春花似錦谈飒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至钾恢,卻和暖如春手素,著一層夾襖步出監(jiān)牢的瞬間鸳址,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評論 1 266
  • 我被黑心中介騙來泰國打工泉懦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稿黍,地道東北人。 一個月前我還...
    沈念sama閱讀 46,351評論 2 360
  • 正文 我出身青樓崩哩,卻偏偏與公主長得像巡球,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邓嘹,可洞房花燭夜當晚...
    茶點故事閱讀 43,509評論 2 348

推薦閱讀更多精彩內(nèi)容

  • vector和string 所有的STL容器都很有用酣栈,但是相比于其他容器,vector和string更常用汹押。本章從...
    lintong閱讀 1,280評論 0 3
  • 容器 條款1:仔細選擇你的容器 C++提供了很多可供程序員使用的容器:(1) 標準STL序列容器:vector矿筝,...
    lintong閱讀 880評論 0 3
  • 迭代器 標準STL容器提供了四種不同的迭代器:iterator、const_iterator棚贾、reverse_it...
    lintong閱讀 317評論 0 1
  • STL算法部分主要由頭文件,,組成窖维。要使用STL中的算法函數(shù)必須包含頭文件,對于數(shù)值算法須包含妙痹,中則定義了一些模板...
    eb51589b1211閱讀 601評論 0 1
  • 標簽(空格分隔): STL 運用STL铸史,可以充分利用該庫的設(shè)計,讓我為簡單而直接的問題設(shè)計出簡單而直接的解決方案细诸,...
    認真學計算機閱讀 1,473評論 0 10