STL是一個(gè)泛型程序庫稽荧,所有組件均有模板構(gòu)成(關(guān)于模板的總結(jié)筆記粒蜈,見我的博客SUMMERY OF TEMPLATE STUDY ),STL好用但并不好懂炕婶,所以侍瑟。唐片。。理解了多少寫多少涨颜。费韭。。在此僅為冰山一角
概觀
STL中主要由容器庭瑰,迭代器星持,算法三個(gè)部件構(gòu)成
- 容器用來管理對象的集合,每一種容器都有自己的優(yōu)缺點(diǎn)弹灭,儲(chǔ)存的方式等都有所不同督暂,使用時(shí)需根據(jù)程序的需求考慮不同容器的效率來選擇
- 迭代器為所有容器提供了一組公共接口,并且鲤屡,每一種容器都提供自己的迭代器
-
STL中把數(shù)據(jù)和算法分開损痰,賦予了STL極大的彈性
下圖演示了三個(gè)部件之間的交互關(guān)系
STL components.png
可以看出,迭代器是容器和算法之間的接口酒来,總體說來卢未,STL使容器與算法分離,使其二者不需要相互依賴堰汉,而迭代器又將算法和不同的容器stick在一起辽社,從而使需要的算法能夠運(yùn)用到不同的容器上(例如可以對多種容器使用find函數(shù),中介便是迭代器)翘鸭,妙哉~
容器
總的來說滴铅,容器可以分為兩類:
- 順序式容器sequence containers
排列順序與置入次序一致,例如vector就乓,deque汉匙,list - 關(guān)聯(lián)式容器associative containers
sort群集,元素的順序取決于特定的排序規(guī)則生蚁,例如set噩翠,multiset,map邦投,multimap.
順序容器
Vector
創(chuàng)建一個(gè)vector,提醒兩個(gè)比較特殊的:
vector<T> v(v,i); //創(chuàng)建一個(gè)容量為n的T型別的vector伤锚,并都初始化為i
int a[] = {1,2,3,4,5,6,7,8,9,10};
vecotr<int> v(a,a+10); //用數(shù)組創(chuàng)建vector
相關(guān)函數(shù)
vector我們平時(shí)使用的比較多,push_back()志衣,empty()都是常用的就不說了屯援,注意vector沒有push_front()猛们,因?yàn)閷τ趘ector來說如果要push_front()效率很低所以不提供這個(gè)函數(shù)
對于vector的at()和operator[],at會(huì)做邊界檢查狞洋,但效率比[]低
刪除元素的操作:
- clear()直接清空
- pop_back()彈出尾部
- erase()借助迭代器清除(傳入迭代器弯淘,也就是位置,也可以是一個(gè)范圍)
iterator erase (iterator position);
iterator erase (iterator first, iterator last);
另外徘铝,我們可以用eraze結(jié)合remove_if(定義在<algorithm>中)來刪除我們指定的元素:
- 首先耳胎,我們需要定義一個(gè)刪選器:用一個(gè)一元對象(unary_function),其關(guān)鍵在于重載operator():
struct ContainsString:public unary_function<string,bool>
{
ContainsString(const string& szMatch) :m_szMatch(szMatch) {}
bool operator()(const string& szStringToMatch)const {
return (szStringToMatch.find(m_szMatch) != -1);
}
string m_szMatch;
};
還記的我們上面所說的erase的用法么惕它,第二個(gè)用法第一個(gè)參數(shù)為eraze的起點(diǎn)怕午,我們的erase函數(shù)這樣寫:
v.erase(remove_if(
v.begin(),
v.end(),
ContainsString("bushuang")
),
v.end());
我們看remove_if的用法:
template <class ForwardIterator, class UnaryPredicate>
ForwardIterator remove_if (ForwardIterator first, ForwardIterator last,
UnaryPredicate pred);
第三個(gè)參數(shù)可以看到就是一個(gè)一元條件,而前兩個(gè)參數(shù)為起止迭代器淹魄,返回值是迭代器郁惜,所以現(xiàn)在就很清楚了,通過remove_if得到一個(gè)迭代器位置甲锡,然后從該位置把后面的東西都刪了兆蕉。
remove_if屬于移除性算法,根據(jù)元素值或某一準(zhǔn)則缤沦,在一個(gè)區(qū)間內(nèi)移除某些元素虎韵。這些算法并不能改變元素的數(shù)量,它們只是以邏輯上的思考缸废,將原本置于后面的“不移除元素”向前移動(dòng)包蓝,覆蓋那些被移除元素而已,它們都返回新區(qū)間的邏輯終點(diǎn)(也就是最后一個(gè)“不移除元素”的下一位置)企量。
Deque
Deque是一個(gè)能夠存放任意型別的雙向隊(duì)列测萎,故比vector多了push_front和pop_front兩個(gè)函數(shù),而我們之前提到過vector因?yàn)樾试虿惶峁┻@兩個(gè)函數(shù)届巩,所以deque必然與vector有不同的內(nèi)存管理方法:大塊的內(nèi)存分配
如果不是要在前面插入硅瞧,一般我們不會(huì)去用Deque,所以也就不多說了恕汇,其用法和vector差不多腕唧,只是效率上的差別
List
list相較于vector和deque,其優(yōu)勢在于可以很快的隨意插入和刪除元素瘾英,對于插入枣接,刪除,替換等操作方咆,效率極高月腋,合并list蟀架,也僅僅只需要節(jié)點(diǎn)的鏈接
相關(guān)函數(shù)
-
void remove (const value_type& val);
直接刪除指定內(nèi)容的元素 - erase與上面差不多瓣赂,不多說了
- 具體說一下splice
void splice (iterator position, list& x); //entire list
void splice (iterator position, list& x, iterator i); //single element
void splice (iterator position, list& x, iterator first, iterator last); //element range
簡單說明一下參數(shù)榆骚,第二個(gè)函數(shù)剪貼單個(gè)元素,第三個(gè)參數(shù)為傳入list x的迭代器煌集;
第三個(gè)函數(shù)后兩個(gè)參數(shù)為傳入list x的迭代器范圍
用以下代碼說明用法:
// splicing lists
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist1, mylist2;
std::list<int>::iterator it;
// set some initial values:
for (int i=1; i<=4; ++i)
mylist1.push_back(i); // mylist1: 1 2 3 4
for (int i=1; i<=3; ++i)
mylist2.push_back(i*10); // mylist2: 10 20 30
it = mylist1.begin();
++it; // points to 2
mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
// mylist2 (empty)
// "it" still points to 2 (the 5th element)
mylist2.splice (mylist2.begin(),mylist1, it);
// mylist1: 1 10 20 30 3 4
// mylist2: 2
// "it" is now invalid.
it = mylist1.begin();
std::advance(it,3); // "it" points now to 30
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
// mylist1: 30 3 4 1 10 20
std::cout << "mylist1 contains:";
for (it=mylist1.begin(); it!=mylist1.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << "mylist2 contains:";
for (it=mylist2.begin(); it!=mylist2.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
里面用到的advance函數(shù)作用是移動(dòng)迭代器(第二參數(shù)可為負(fù)數(shù))
我們在使用splice的時(shí)候妓肢,注意iterator 的位置,advance函數(shù)第二參數(shù)不要讓迭代器超過范圍苫纤,否則將導(dǎo)致不可預(yù)知的問題碉钠。
- 另外,list還有sort()與merge()函數(shù)卷拘,
參考
書籍:The C plus plus Standard Library A Tutorial and Reference (2nd)
網(wǎng)站:http://cplusplus.com
未完待續(xù)(下周繼續(xù))...