primer5:chap09順序容器
阿新 • • 發佈:2021-01-12
chap09、順序容器 291(317/864)
- 一個容器就是一些特定型別物件的集合。順序容器(sequential container)的順序不依賴於元素的值,而是與元素加入容器時的位置相對應。
9.1、順序容器概述
- 所有順序容器都提供了快速順序訪問元素的能力。但以下方面都有不同的效能折中:
- 向容器新增或從容器中刪除元素的代價
- 非順序訪問容器中元素的代價
- 順序容器型別
- vector:快速隨機訪問。尾部之外插入/刪除慢
- deque:快速隨機訪問。頭尾插入/刪除快
- list:雙向順序訪問。任何位置插入/刪除快
- forward_list:單向順序訪問。任何位置插入/刪除快
- array:固定大小,快速隨機訪問,不能新增/刪除元素
- string:與vector相似,專門用於儲存字元。隨機訪問快。尾部插入/刪除快。
- 確定使用哪種順序容器
- 除非你有很好的理由選擇其他容器,否則應使用vector。
- 如果程式要求隨機訪問元素,應使用vector或deque。
- 中間插入或刪除元素:list或forward_list
- 頭尾插入/刪除,但不會在中間插入/刪除,用deque。
9.2、容器庫概覽
- 0
- 本節,將介紹對所有容器都適用的操作。
- 一般來說,每個容器都定義在一個頭檔案中,檔名與型別名相同。容器均定義為模板類。
list<Sales_data> // 儲存Sales_data物件的list
- 對容器可以儲存的元素型別的限制
vector<vector<string>> lines;//vector的vector
- 某些類沒有預設建構函式,但在構造這種容器時不能只傳遞給它一個元素數目引數:
vector<noDefault> v2(10);//錯誤:必須提供一個元素初始化器
,比如這樣vector<noDefault> v1(10, init);
- 表9.2:容器操作,295(321/864)
9.2.1、迭代器
-
0
- 迭代器有著公共的介面:
-
迭代器範圍
- 左閉合區間
[begin,end)
範圍自begin開始,於end之前結束。即不包含end。
- 左閉合區間
-
對構成範圍的迭代器的要求
-
使用左閉合範圍蘊含的程式設計假定
while(begin != end){ *begin = val; //正確:範圍非空,因此begin指向一個元素 ++begin; //移動迭代器,獲取下一個元素 }
9.2.2、容器型別成員
- 每個容器都定義了多個型別。我們已經使用過其中三種:
size_type、iterator、const_iterator
。
//iter是通過list<string>定義的一個迭代器型別
list<string>::iterator iter;
//count是通過vector<int>定義的一個difference_type型別
vector<int>::difference_type count;
9.2.3、begin和end成員
- 當我們對一個非常物件呼叫這些成員時,得到的是返回iterator的版本。
- 只有在對一個const物件呼叫這些函式時,才會得到一個const版本。
- 當不需要寫訪問時,應使用cbegin和cend。以c開頭的版本是const_iterator的。
9.2.4、容器定義和初始化
- 0
- 每個容器型別都定義了一個預設建構函式。除array之外。
- 表9.3:容器定義和初始化 299(325/864)
- 將一個容器初始化為另一個容器的拷貝
- (1)可以直接拷貝整個容器
- (2)array除外,拷貝由一個迭代器對指定的元素範圍
deque<string> authList(authors.begin(),it);//拷貝元素,直到(但不包括)it指向的元素
//每個容器有三個元素,用給定的初始化器進行初始化
list<string> authors = {"Milton","Shakespeare","Austen"};
vector<const char*> articles = {"a","an","the"};
list<string> list2(authors);//正確:型別匹配
deque<string> authList(authors);//錯誤:容器型別不匹配
vector<string> words(articles); //錯誤:容器型別必須匹配
//正確:可以將const char*元素轉換為string
forward_list<string> words(articles.begin(), articles.end());
- 列表初始化
vector<const char*> articles = {"a","an","the"};
- 與順序容器大小相同的建構函式
vector<int> ivec(10,-1);//10個int元素,每個都初始化為-1
list<string> svec(10,"hi!");//10個strings;每個都初始化為“hi!”
forward_list<int> ivec(10);//10個元素,每個都初始化為0
deque<string> svec(10);//10個元素,每個都是空string
- 標準庫array具有固定大小
9.2.5、賦值和swap
- 0
- 表9.4:容器賦值運算 302(328/864)
- 使用assgin(僅順序容器)
list<string>names;
vector<const char*> oldstyle;
names = oldstyle; //錯誤:容器型別不匹配
//正確:可以將const char*轉換為string
names.assign(oldstyle.cbegin(),oldstyle.cend());
//等價於slist1.clear();
//後跟slist1.insert(slist1.begin(),10,"Hiya!");
list<string> slist1(1);//1個元素,為空string
slist1.assign(10,"Hiya!");//10個元素,每個都是"Hiya!"
- 使用swap
9.2.6、容器大小操作
- 0
- size()返回容器中元素的數目
- empty當size為0時返回布林值true,否則返回false
- max_size返回一個大於或等於該型別容器所能容納的最大元素數的值
9.2.7、關係運算符
9.3、順序容器操作
9.3.1、向順序容器新增元素
9.3.2、訪問元素
9.3.3、刪除元素
9.3.4、特殊的forward_list
9.3.5、改變容器大小
9.3.6、容器操作可能使迭代器
9.4、vector物件是如何增長的
9.5、額外的string操作
9.5.1、構造string的其他方
9.5.2、改變string的其他方
9.5.3、string搜尋操作
9.5.4、compare函式
9.5.5、數值轉換
9.6、容器介面卡
小結 332(358/864)
履歷
- 2020-06-03整理了初稿。
- 2021-01-12開始進行重讀英文版後再進行整理,主要是9.1節。