順序容器 - 2【C++ Primer 學習筆記 - 第九章】

list<int> ilist(10);
// 空容器:*ilist.begin() 無法解引用
// 空容器:back()、front() 操作,未定義
if(!ilist.empty())
{
	list<int>::reference val = *ilist.begin();
	list<int>::reference val2 = ilist.front();

	list<int>::reference last = *--ilist.end();
	list<int>::reference last2 = ilist.back();
}


訪問順序容器內元素的操作
c.back() 返回容器c 的最後一個元素的引用. c 爲空,操作未定義
c.front() 返回容器c 的第一個元素的引用. c 爲空,操作未定義
c[n] 返回下標爲n 的元素的引用
如果 n<0 或者 n>=c.size(), 操作未定義
只適用於 vector 和 deque 容器
c.at(n) 返回下標爲 n 的元素的引用。如果下標越界,操作未定義
只適用於 vector 和 deque 容器









at() 成員函數,類似於下標操作,如果下標無效, at 函數會拋出 out_of_range 異常






刪除順序容器內元素的操作
c.erase(p) 刪除迭代器 p 所指向的元素
返回一個迭代器,指向被刪除元素後面的元素。
如果 p 指向最後一個元素,則返回的迭代器指向容器的超出末端的下一位置。
如果 p 指向超出末端的下一位置,則該函數未定義。
c.erase(b, e) 刪除迭代器b 和 e 所標記的範圍內所有的元素
返回一個迭代器,指向被刪除元素段 後面的元素. 
如果 e 本身就是指向超出末端的下一位置的迭代器,則返回的迭代器也指向超出末端的下一位置
c.clear() 刪除容器 c 內的所有元素。返回 void 類型
c.pop_back() 刪除容器 c 內的最後一個元素。返回 void 類型. 如果容器 c 爲空,則函數未定義
c.pop_front() 刪除容器 c 內的第一個元素。返回 void 類型. 如果容器 c 爲空,則函數未定義
只適用於 list 或者 deque 容器










#include <algorithm>

list<string> websiteList;
websiteList.push_back("google");
websiteList.push_back("baidu");
websiteList.push_back("taobao");

string searchStr("google");
list<string>::iterator iter = find(websiteList.begin(), websiteList.end(), searchStr);
if(iter!= websiteList.end())
{
	websiteList.erase(iter);
}

// 同下:websiteList.erase(websiteList.begin(), websiteList.end());
websiteList.clear();


順序容器的賦值操作
c1 = c2 刪除容器 c1 的所有元素,然後將 c2 的元素複製給 c1。 c1 和 c2 的類型必須相同
c1.swap(c2) 交換 c1、c2 的內容,調用成功後,c1 存放的是 c2 原來的元素,c2 存放的是 c1 原來的元素
c1 和 c2 的類型必須完全相同。此函數執行速度通常要比,將c2 複製到 c1 的操作快
c.assign(b, e) 重設c 的元素,將迭代器 b 和 e 標記的範圍內所有的元素複製到c 中。
b、e 必須都不是指向 c 中元素的迭代器。因爲該函數是先刪除容器中原來存儲的所有元素
c.assign(n, t) 重設 c , 存儲 n 個值爲 t 的元素







list<string> slist1;
slist1.push_back("google");
slist1.push_back("baidu");

list<string> slist2;
// 等效於: slist2 = slist1;	
// 但是,如果 list<char *> slist1,則,只能使用 assign() 操作
slist2.assign(slist1.begin(), slist1.end());

// 等效於:
// slist1.clear();
// slist1.insert(slist1.begin(), 10, "test");
slist1.assign(10, "test");

// 此操作不會導致迭代器失效
// 如,list<string>::iterator iter = slist1.begin();
// 那麼,執行 swap 之後, iter 指向 slist2.begin()
slist1.swap(slist2);


vector 容器,爲支持快速的隨機訪問, vector 容器的元素以連續的方式存放
標準庫會以最小的代價來連續存儲元素
爲了使 vector 容器實現快速的內存分配,其實際分配的容量要比所需的空間多一些。
分配的額外內存容量,因庫的不同實現而不同。其性能非常好。
大部分應用下,使用 vector 是最好的


list 容器中,添加一個新元素,標準庫只需要創建元素,
然後,將其連接在已經存在的鏈表中,而不必重新分配內存,也不必複製任何已存在的元素


capacity 和 reserve 成員

vector<int> ivec;
cout << "ivec.size():" << ivec.size() << endl
	<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():0
// ivec.capacity():0


for(vector<int>::size_type ix = 0; ix != 15; ++ix)
	ivec.push_back(ix);

cout << "ivec.size():" << ivec.size() << endl
	<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():15
// ivec.capacity():19

ivec.clear();
ivec.reserve(25);
while(ivec.size() != ivec.capacity())
	ivec.push_back(88);

cout << "ivec.size():" << ivec.size() << endl
	<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():25
// ivec.capacity():25


ivec.push_back(99);
cout << "ivec.size():" << ivec.size() << endl
	<< "ivec.capacity():" << ivec.capacity() << endl;
// ivec.size():26
// ivec.capacity():37


容器的選用

vector 和 deque 都支持快速隨機訪問,
vector ,執行插入和刪除操作時,如果不是容器末尾進行操作,那麼它的開銷較大

deque 容器,雙端隊列,在容器首、尾 的插入和刪除操作都非常快。
deque 容器中,首、尾,插入元素操作,不會使任何迭代器失效
而在首、尾 刪除元素,則會使指向被刪除元素的迭代器失效。
任何其他位置的插入、刪除,會使指向該容器元素的所有迭代器失效。

list 容器可以在任意位置實現快速的插入和刪除,但是,隨機訪問的開銷較大
list 容器表示不連續的內存區域,允許向前或向後逐個遍歷元素,
訪問 list 容器中的某個元素,需要遍歷相關的所有其他元素
在 list 容器的元素之間移動的唯一方法是順序跟隨指針,
比如,從5號元素,移動到15號元素,必須遍歷5-15之間的所有元素

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章