C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)
C++ 標準庫可以分為兩部分:
- 標準函數庫: 這個庫是由通用的、獨立的、不屬于任何類的函數組成的。函數庫繼承自
C語言。 - 面向對象類庫: 這個庫是類及其相關函數的集合。
C++ 標準庫包含了所有的 C 標準庫,為了支持類型安全,做了一定的添加和修改。
標準函數庫
標準函數庫分為以下幾類:
- 輸入/輸出 I/O
- 字符串和字符處理
- 數學
- 時間、日期和本地化
- 動態分配
- 其他
- 寬字符函數
面向對象類庫
標準的 C++ 面向對象類庫定義了大量支持一些常見操作的類,比如輸入/輸出 I/O、字符串處理、數值處理。面向對象類庫包含以下內容:
- 標準的 C++ I/O 類
- String 類
- 數值類
- STL 容器類
- STL 算法
- STL 函數對象
- STL 迭代器
- STL 分配器
- 本地化庫
- 異常處理類
- 雜項支持庫
簡單地說,標準模板庫( STL )是一組模板類和函數,向程序員提供了:
- 用于存儲信息的容器;
- 用于訪問容器存儲的信息的迭代器;
- 用于操作容器內容的算法。
1. STL 容器
容器是用于存儲數據的 STL 類, STL 提供了兩種類型的容器類:
- 順序容器;
- 關聯容器。
另外, STL 還提供了被稱為容器適配器(Container Adapter)的類,它們是順序容器和關聯容器的變種,包含的功能有限,用于滿足特殊的需求。
1.1 順序容器
顧名思義,順序容器按順序存儲數據,如數組和列表。順序容器具有插入速度快但查找操作相對較慢的特征。
STL 順序容器如下所示。
-
std::vector:操作與動態數組一樣,在最后插入數據;可將vector視為書架,您可在一端添加和拿走圖書。 -
std::deque:與std::vector類似,但允許在開頭插入或刪除元素。 -
std::list:操作與雙向鏈表一樣。可將它視為鏈條,對象被連接在一起,您可在任何位置添加或刪除對象。 -
std::forward_list:類似于std::list,但是單向鏈表,只能沿一個方向遍歷。
STL vector 類與數組類似,允許隨機訪問元素,即可使用下標運算符 [] 指定元素在 vector 中的位置(索引),從而直接訪問或操作元素。另外, STL vector 是動態數組,因此能夠根據應用程序在運行階段的需求自動調整長度。
為保留數組能夠根據位置隨機訪問元素的特征,大多數 STL vector 實現都將所有元素存儲在連續的存儲單元中,因此需要調整長度的 vector 通常會降低應用程序的性能,這取決于它包含的對象類型。
可將 STL list 類視為普通鏈表的 STL 實現。雖然 list 中的元素不能像 STL vector 中的元素那樣隨機訪問,但 list 可使用不連續的內存塊組織元素,因此它不像 std::vector 那樣需要給內部數組重新分配內存,進而導致性能問題。
1.2 關聯容器
關聯容器按指定的順序存儲數據,就像詞典一樣。這將降低插入數據的速度,但在查詢方面有很大的優勢。
STL 提供的關聯容器如下所示。
std::set:存儲各不相同的值,在插入時進行排序;容器的復雜度為對數。std::unordered_set:存儲各不相同的值,在插入時進行排序;容器的復雜度為常數。這種容器是 C++11 新增的。std::map:存儲鍵-值對,并根據唯一的鍵排序;容器的復雜度為對數。std::unordered_map:存儲鍵-值對,并根據唯一的鍵排序;容器的復雜度為對數。這種容器是 C++11 新增的。std::multiset:與set類似,但允許存儲多個值相同的項,即值不需要是唯一的。std::unordered_multiset:與unordered_set類似,但允許存儲多個值相同的項,即值不需要是唯一的。這種容器是 C++11 新增的。std::multimap:與map類似,但不要求鍵是唯一的。std::unordered_multimap:與unordered_map類似,但不要求鍵是唯一的。這種容器是 C++11 新增的。
1.3 容器適配器
容器適配器(Container Adapter)是順序容器和關聯容器的變種,其功能有限,用于滿足特定的需求。主要的適配器類如下所示。
std::stack:以LIFO(后進先出)的方式存儲元素,讓您能夠在棧頂插入(壓入)和刪除(彈出)元素。std::queue:以FIFO(先進先出)的方式存儲元素,讓您能夠刪除最先插入的元素。std::priority_queue:以特定順序存儲元素,因為優先級最高的元素總是位于隊列開頭。
2. STL 迭代器
最簡單的迭代器是指針。給定一個指向數組中的第一個元素的指針,可遞增該指針使其指向下一個元素,還可直接對當前位置的元素進行操作。
STL 中的迭代器是模板類,從某種程度上說,它們是泛型指針。這些模板類讓程序員能夠對 STL 容器進行操作。注意,操作也可以是以模板函數的方式提供的 STL 算法,迭代器是一座橋梁,讓這些模板函數能夠以一致而無縫的方式處理容器,而容器是模板類。
STL 提供的迭代器分兩大類。
-
輸入迭代器:通過對輸入迭代器解除引用,它將引用對象,而對象可能位于集合中。最嚴格的輸入迭代器確保只能以只讀的方式訪問對象。
-
輸出迭代器:輸出迭代器讓程序員對集合執行寫入操作。最嚴格的輸出迭代器確保只能執行寫入操作。
上述兩種基本迭代器可進一步分為三類。
- 前向迭代器:這是輸入迭代器和輸出迭代器的一種細化,它允許輸入與輸出。前向迭代器可以是
const的,只能讀取它指向的對象;也可以改變對象,即可讀寫對象。前向迭代器通常用于單向鏈表。 - 雙向迭代器:這是前向迭代器的一種細化,可對其執行遞減操作,從而向后移動。雙向迭代器通常用于雙向鏈表。
- 隨機訪問迭代器:這是對雙向迭代器的一種細化,可將其加減一個偏移量,還可將兩個迭代器相減以得到集合中兩個元素的相對距離。隨機訪問迭代器通常用于數組。
3. STL 算法
查找、排序和反轉等都是標準的編程需求,不應讓程序員重復實現這樣的功能。因此 STL 以 STL 算法的方式提供這些函數,通過結合使用這些函數和迭代器,程序員可對容器執行一些最常見的操作。
最常用的 STL 算法如下所示。
std::find:在集合中查找值。std::find_if:根據用戶指定的謂詞在集合中查找值。std::reverse:反轉集合中元素的排列順序。std::remove_if:根據用戶定義的謂詞將元素從集合中刪除。std::transform:使用用戶定義的變換函數對容器中的元素進行變換。
這些算法都是 std 命名空間中的模板函數,要使用它們,必須包含標準頭文件 <algorithm> 。
4. 迭代器在容器和算法之間交互
下面程序使用了 STL 順序容器 std::vector (它類似于動態數組)來存儲一些整數,再使用 std::find 算法在集合中查找一個整數。請注意迭代器是如何在這兩者之間搭建橋梁的。
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main ()
{// A dynamic array of integersvector <int> intArray;// Insert sample integers into the arrayintArray.push_back (50);intArray.push_back (2991);intArray.push_back (23);intArray.push_back (9999);cout << "The contents of the vector are: " << endl;// Walk the vector and read values using an iteratorvector <int>::iterator arrIterator = intArray.begin ();while (arrIterator != intArray.end ()){// Write the value to the screencout << *arrIterator << endl;// Increment the iterator to access the next element++ arrIterator;}// Find an element (say 2991) using the 'find' algorithmvector <int>::iterator elFound = find (intArray.begin () , intArray.end (), 2991);// Check if value was foundif (elFound != intArray.end ()){// Determine position of element using std::distanceint elPos = distance (intArray.begin (), elFound);cout << "Value "<< *elFound;cout << " found in the vector at position: " << elPos << endl;}return 0;
}
輸出結果:
The contents of the vector are:
50
2991
23
9999
Value 2991 found in the vector at position: 1
上述代碼演示了如何使用迭代器遍歷向量。迭代器是一個接口,將算法( find )連接到其要操作的數據所屬的容器(如 vector )。
第 20 行聲明了迭代器對象 arrIterator ,并將其初始化為指向容器開頭,即 vector 的成員函數 begin() 返回的值。
第 22~29 行演示了如何在循環中使用該迭代器遍歷并顯示 vector 包含的元素,這與顯示靜態數組的內容極其相似。迭代器的用法在所有 STL 容器中都相同。
所有容器都提供了 begin() 函數和 end() 函數,其中前者指向第一個元素,后者指向容器中最后一個元素的后面。這就是第 22 行的 while 循環在 end() 前面而不是 end() 處結束的原因。
第 32 行演示了如何使用 find 在 vector 中查找值。 find 操作的結果也是一個迭代器,通過將該迭代器與容器末尾進行比較,可判斷 find 是否成功,如第 36 行所示。如果找到了元素,便可對該迭代器解除引用(就像對指針解除引用一樣)以顯示該元素。
算法 distance 計算找到的元素的所處位置的偏移量。上述代碼所有的 vector 都替換為 deque ,代碼仍能通過編譯并完美地運行。這表明迭代器讓您能夠輕松地使用算法和容器。
5. STL 容器類特點
6. STL 字符串類
STL 提供了一個專門為操縱字符串而設計的模板類: std::basic_string<T> ,該模板類的兩個常用具體化如下所示。
std::string:基于char的std::basic_string具體化,用于操縱簡單字符串。std::wstring:基于wchar_t的std::basic_string具體化,用于操縱寬字符串,通常用于存儲支持各種語言中符號的Unicode字符。
總結
以上是生活随笔為你收集整理的C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一罐蛋白粉要多少钱?划算吗?
- 下一篇: 2022-2028年中国六氟化硫行业市场