聲明:這個博文所有內容均來自於C++標準庫-自學教程與參考手冊(第二版)英文版 上冊。如果轉載,務必附帶本聲明,並註明出處。
STL為了滿足不同需求而創造了一些列通用的容器
** 一、Containers
**
1、Vector
使用vector需要添加標頭檔< vector>,vector也包含在std namespace.
vector的所有函數可以在這裡查到。
這裡在囉嗦下常用的幾個函數。
begin()、end()、front()、back():前兩個用於擷取第一個和最後一個迭代器的,後兩個是用於擷取第一個和最後一個元素的。
push_back()、pop_back():添加、刪除最後一個元素。
resize()重設vector大小,同時可以指定重設後的值。不過這種重設是只取前面的n個元素。
[]、at(),用於索引。
data(),返回vector中使用者儲存資料的首地址。
vector的使用相當簡單,使用也廣泛。不過如果資料管理簡單,而且資料個數不變動的,建議直接使用數組以獲得更高的效率。
2、Deque
deque是“double-ended queue”的縮寫,是一種可以在兩端伸長或縮短的雙向數組。所以在兩端插入資料是非常快的,但是在中間插入會很慢,因為部分元素需要移動位置。Deque就是比vector多了個雙向的性質。
#include <iostream>#include <vector>#include <deque>int main(){ std::vector<int> vInt; vInt.push_back(5201314); std::deque<double> dqDouble; for (int i = 0; i < 8; ++i) { if (i % 2 == 0) dqDouble.push_back(i * 1.0); else { dqDouble.push_front( i * 1.0 ); } } for (auto iter : dqDouble) std::cout << iter << " "; std::cout << std::endl;}
3、Array
Array是STL提供的用於管理固定大小的容器。因此在使用時,它的大小是不能改變的。這個和普通的數組差不多,無法動態分配。同時C++11的Array也不支援多維陣列。感覺用處不是很大。
4、List
在C++11裡面有兩種鏈表,一種就是list<>,它是一種雙向鏈表,還有一種是forward_list;
使用List的好處就在於插入或者刪除元素所佔用的時間是很短的,因為它僅需要改變指標,而不用移動元素。但是List不支援random access(可以翻譯為隨機擷取嗎。),也就是說它無法通過索引來擷取元素,只能從第一個一直往下推導。這樣做的問題在於:當鏈表很長時,如果想擷取最後一個元素也許要消耗較長時間。forward_list讓鏈表只能朝著一個方向生長,其他方面與list<>類似。
int main(){ std::list<char> cList; for (char c = 'a'; c <= 'z'; ++c) cList.push_back(c); for (auto &elem : cList) std::cout << elem << ' '; std::cout << std::endl; return 0;}
二、Associative Containers
Associative containers會根據特定的定序自動將元素排序,元素可能是任意類型或者是pair的。預設情況下,它會通過運算子 “<”來對普通value(或者pair裡面的key 或value)來排序。但使用者也可以自訂定序。
Associative containers 典型的實現就是二叉樹。每個元素都只有一個父節點和兩個子節點(或者沒有子節點)。它的主要好處在於尋找快速。
所有的Associative containers 都有一個可選的模板參數用於排序。
int main(){ std::multiset<std::string> cities{ "Braunschweig", "Hanover", "Frankfurt", "New York", "Chicago", "Toronto", "Paris", "Frankfurt"}; // print each element: for (const auto& elem : cities) { std::cout << elem.data() << " ";//本來書上是直接 std::cout << elem << " " ;但是VS2013報錯了,我改了之後可以正常運行。 } std::cout << std::endl; // insert additional values: cities.insert({ "London", "Munich", "Hanover", "Braunschweig" }); // print each element: for (const auto& elem : cities) { std::cout << elem.data() << " "; } std::cout << std::endl;}
輸出結果為:
Braunschweig Chicago Frankfurt Frankfurt Hanover New York Paris Toronto
Braunschweig Braunschweig Chicago Frankfurt Frankfurt Hanover Hanover London Munich New York Paris Toronto
請按任意鍵繼續…
下面是一個關於multimap的例子:
int main(){ multimap<int, string> coll = { { 5, "tagged" }, { 2, "a" }, { 1, "this" }, { 4, "of" }, { 6, "strings" }, { 1, "is" }, { 3, "multimap" } }; //這裡書本上是 /*multimap<int, string> coll; // container for int/string values // insert some elements in arbitrary order // - a value with key 1 gets inserted twice coll = { { 5, "tagged" }, { 2, "a" }, { 1, "this" }, { 4, "of" }, { 6, "strings" }, { 1, "is" }, { 3, "multimap" } };*/ //但是運行報錯,不能這樣初始化。cpp reference給出的使用make_pair方式 // print all element values // - element member second is the value for (auto elem : coll) { cout << elem.second.data() << endl; //這裡書本中是直接使用elem.second來輸出,但是VS2013報錯 } cout << endl;}
三、Unordered Containers
unordered containers,顧名思義,裡面的元素是沒有特定排序的。它就像一個袋子一樣,只是裝東西,但是這個東西在這個袋子的哪個地方是無法預Crowdsourced Security Testing道的。如果有兩個一樣的這樣的容器,就算你放入資料一樣,最後得到的順序還是有可能不一樣。unordered containers典型的實現就是雜湊表。在內部,這種容器是一系列的鏈表。通過使用雜湊函數,元素的位置就可以得到處理。設計這種容器的目的就在於讓你能夠快速擷取元素,因為有雜湊表。
具體類型有:
• An unordered set is a collection of unordered elements, where each element may occur only
once. Thus, duplicates are not allowed.
• An unordered multiset is the same as an unordered set except that duplicates are allowed. Thus,
an unordered multiset may contain multiple elements that have the same value.
• An unordered map contains elements that are key/value pairs. Each key may occur only once,
so duplicate keys are not allowed. An unordered map can also be used as an associative array,
an array that has an arbitrary index type (see Section 6.2.4, page 185, for details).
• An unordered multimap is the same as an unordered map except that duplicates are allowed.
Thus, an unordered multimap may contain multiple elements that have the same key. An unordered multimap can also be used as dictionary (see Section 7.9.7, page 383, for an example).
int main(){ //需要包含標頭檔<unordered_set> unordered_multiset<string> cities{ "Braunschweig", "Hanover", "Frankfurt", "New York", "Chicago", "Toronto", "Paris", "Frankfurt"}; // print each element: for (const auto& elem : cities) { cout << elem.data() << " "; } cout << endl; // insert additional values: cities.insert({ "London", "Munich", "Hanover", "Braunschweig" }); // print each element: for (const auto& elem : cities) { cout << elem.data() << " "; } cout << endl;}
再來一個unordered_map的例子:
int main(){ //需要#include <unordered_map> unordered_map<string, double> coll{ { "tim", 9.9 }, { "struppi", 11.77 }}; // square the value of each element: for (pair<const string, double>& elem : coll) { elem.second *= elem.second; } // print each element (key and value): for (const auto& elem : coll) { cout << elem.first.data() << ": " << elem.second << endl; }}
四、Associative Arrays
直接先上代碼吧:
int main(){ unordered_map<string, double> coll; coll["A"] = 0.1; coll["B"] = 0.2; coll["Pi"] = 3.1415926; coll["money"] = -99.9; for (auto iter : coll) cout << iter.first.data() << ":" << iter.second << endl;}
這段代碼像極了python的字典。這裡的 [] 運算子用於提取map裡面的pair裡面的第一個元素,如果這個元素存在,那個就直接賦值了,如果不存在,那麼就添加後賦值。