C++面試總結(四)標準庫
1.什麼是標準庫(STL)?
C++ STL(標準模板庫)是一套功能強大的 C++ 模板類,提供了通用的模板類和函式,這些模板類和函式可以實現多種流行和常用的演算法和資料結構,如向量、連結串列、佇列、棧。
2.C++ 標準模板庫的核心三個元件組成?
3.string
C++ 從 C 繼承的字串概念仍然是以 '\0' 為結束符的 char 陣列。C++ 標準庫中的 string class 可以將 string 作為一個型別,可以實現複製、賦值和比較,不必擔心記憶體大小及佔用記憶體實際長度等具體問題。
STL 中只有一個字串類,即 basic_string。類 basic_string 實現管理以 \0
(1)string 類提供的各種操作函式大致分為八類:構造器和析構器、大小和容量、元素存取、字 符串比較、字串修改、字串接合、I/O 操作以及搜尋和查詢。
string 類的所有成員函式
函式名稱 | 功能 |
---|---|
建構函式 | 產生或複製字串 |
解構函式 | 銷燬字串 |
=,assign | 賦以新值 |
Swap | 交換兩個字串的內容 |
+ =,append( ),push_back() | 新增字元 |
insert () | 插入字元 |
erase() | 刪除字元 |
clear () | 移除全部字元 |
resize () | 改變字元數量 |
replace() | 替換字元 |
+ | 串聯字串 |
==,! =,<,<=,>,>=,compare() | 比較字串內容 |
size(),length() | 返回字元數量 |
max_size () | 返回字元的最大可能個數 |
empty () | 判斷字串是否為空 |
capacity () | 返回重新分配之前的字元容量 |
reserve() | 保留記憶體以儲存一定數量的字元 |
[],at() | 存取單一字元 |
>>,getline() | 從 stream 中讀取某值 |
<< | 將值寫入 stream |
copy() | 將內容複製為一個 C - string |
c_str() | 將內容以 C - string 形式返回 |
data() | 將內容以字元陣列形式返回 |
substr() | 返回子字串 |
find() | 搜尋某子字串或字元 |
begin( ),end() | 提供正向迭代器支援 |
rbegin(),rend() | 提供逆向迭代器支援 |
get_allocator() | 返回配置器 |
(2) string建構函式和解構函式詳解
//建構函式
string strs //生成空字串
string s(str) //生成字串str的複製品
string s(str, stridx) //將字串str中始於stridx的部分作為建構函式的初值
string s(str, strbegin, strlen) //將字串str中始於strbegin、長度為strlen的部分作為字串初值
string s(cstr) //以C_string型別cstr作為字串s的初值
string s(cstr,char_len) //以C_string型別cstr的前char_len個字串作為字串s的初值
strings(num, c) //生成一個字串,包含num個c字元
strings(strs, beg, end) //以區間[beg, end]內的字元作為字串s的初值
//解構函式
~string() //銷燬所有記憶體,釋放記憶體
//注意,不能使用字元或者整數去初始化字串。
std::string s('x'); //錯誤
std::string s("x"); //正確
std::string s(1, 'x'); //正確
(3)C++獲取字串長度詳解
String 型別物件包括三種求解字串長度的函式:size() 和 length()、 maxsize() 和 capacity():
- size() 和 length():這兩個函式會返回 string 型別物件中的字元個數,且它們的執行效果相同。
- max_size():max_size() 函式返回 string 型別物件最多包含的字元數。一旦程式使用長度超過 max_size() 的 string 操作,編譯器會丟擲 length_error 異常。
- capacity():該函式返回在重新分配記憶體之前,string 型別物件所能包含的最大字元數。
string 型別物件還包括一個 reserve() 函式。呼叫該函式可以為 string 型別物件重新分配記憶體。重新分配的大小由其引數決定。reserve() 的預設引數為 0。
(4)string獲取字串元素:[]和at()
字串中元素的訪問是允許的,一般可使用兩種方法訪問字串中的單一字元:下標操作符[] 和 成員函式at()。兩者均返回指定的下標位置的字元。第 1 個字元索引(下標)為 0,最後的字元索引為 length()-1。
需要注意的是,這兩種訪問方法是有區別的:
- 下標操作符 [] 在使用時不檢查索引的有效性,如果下標超出字元的長度範圍,會示導致未定義行為。對於常量字串,使用下標操作符時,字串的最後字元(即 '\0')是有效的。對應 string 型別物件(常量型)最後一個字元的下標是有效的,呼叫返回字元 '\0'。
- 函式 at() 在使用時會檢查下標是否有效。如果給定的下標超出字元的長度範圍,系統會丟擲 out_of_range 異常。
(5)C++ string字串比較方法詳解
Basic_string 類模板既提供了 >、<、==、>=、<=、!= 等比較運算子,還提供了 compare() 函式,其中 compare() 函式支援多引數處理,支援用索引值和長度定位子串進行比較。該函式返回一個整數來表示比較結果。如果相比較的兩個子串相同,compare() 函式返回 0,否則返回非零值。
4.容器
容器是用來管理某一類物件的集合,包括序列式容器和關聯式容器。
STL 中已經提供的容器主要如下:
- vector <T>:一種向量。
- list <T>:一個雙向連結串列容器,完成了標準 C++ 資料結構中連結串列的所有功能。
- queue <T>:一種佇列容器,完成了標準 C++ 資料結構中佇列的所有功能。
- stack <T>:一種棧容器,完成了標準 C++ 資料結構中棧的所有功能。
- deque <T>:雙端佇列容器,完成了標準 C++ 資料結構中棧的所有功能。
- priority_queue <T>:一種按值排序的佇列容器。
- set <T>:一種集合容器。
- multiset <T>:一種允許出現重複元素的集合容器。
- map <key, val>:一種關聯陣列容器。
- multimap <key, val>:一種允許出現重複 key 值的關聯陣列容器。
序列式容器:vector,list,deque,queue,stack,priority_queue
關聯式容器:map,set
5.序列式容器的種類?
序列容器以線性序列的方式儲存元素。它沒有對元素進行排序,元素的順序和儲存它們的順序相同。以下有5種標準的序列容器,每種容器都具有不同的特性:
- array<T,N>(陣列容器)是一個長度固定的序列,有 N 個 T 型別的物件,不能增加或刪除元素。
- vector<T>(向量容器)是一個長度可變的序列,用來存放 T 型別的物件。必要時,可以自動增加容量,但只能在序列的末尾高效地增加或刪除元素。
- deque<T>(雙向佇列容器)是一個長度可變的、可以自動增長的序列,在序列的兩端都不能高效地增加或刪除元素。
- list<T>(連結串列容器)是一個長度可變的、由 T 型別物件組成的序列,它以雙向連結串列的形式組織元素,在這個序列的任何地方都可以高效地增加或刪除元素。訪問容器中任意元素的速度要比前三種容器慢,這是因為 list<T> 必須從第一個元素或最後一個元素開始訪問,需要沿著連結串列移動,直到到達想要的元素。
- forward list<T>(正向連結串列容器)是一個長度可變的、由 T 型別物件組成的序列,它以單鏈表的形式組織元素,是一類比連結串列容器快、更節省記憶體的容器,但是它內部的元素只能從第一個元素開始訪問。
函式成員 | array<T,N> | vector<T> | deque<T> |
---|---|---|---|
begin() - 返回幵始迭代器 | 是 | 是 | 是 |
end() - 返回結束迭代器 | 是 | 是 | 是 |
rbegin() - 返回反向'開始迭代器 | 是 | 是 | 是 |
rend() - 返回反向結束迭代器 | 是 | 是 | 是 |
cbegin() - 返M const開始迭代器 | 是 | 是 | 是 |
cend() - 返回const結束迭代器 | 是 | 是 | 是 |
crbegin() - 返回const反向開始迭代器 | 是 | 是 | 是 |
crend() - 返回const反向結束迭代器 | 是 | 是 | 是 |
assign() - 用新元素替換原有內容 | - | 是 | 是 |
operator=() - 複製同類型容器的元素,或者用初始化列表替換 現有內容 | 是 | 是 | 是 |
size() - 返回實際元素個數 | 是 | 是 | 是 |
max_size() - 返回元素個數的設大值 | 是 | 是 | 是 |
capacity() - 返回當前容量 | - | 是 | - |
empty() - 返回true,如果容器中沒有元素的話 | 是 | 是 | 是 |
resize() - 改變實際元素的個數 | - | 是 | 是 |
shrink _to_fit() - 將記憶體減少到等於當前元素實際所使用的大小 | - | 是 | 是 |
front() - 返回第一個元素的引用 | 是 | 是 | 是 |
back() - 返回鋮後一個元素的引用 | 是 | 是 | 是 |
operator[]() - 使用索弓丨訪問元素 | 是 | 是 | 是 |
at() - 使用經過邊界檢査的索引訪問元素 | 是 | 是 | 是 |
push_back() - 在序列的尾部新增一個元素 | - | 是 | 是 |
insert() - 在指定的位置插入一個或多個元素 | - | 是 | 是 |
emplace() - 在指定的位置直接生成一個元素 | - | 是 | 是 |
emplace_back() - 在序列尾部生成一個元素 | - | 是 | 是 |
pop_back() - 移出序列尾部的元素 | - | 是 | 是 |
erase() - 移出一個元素或一段元素 | - | 是 | 是 |
clear() - 移出所苻的元素,容器大小變為 0 | - | 是 | 是 |
swap() - 交換兩個容器的所有元素 | 是 | 是 | 是 |
data() - 返回包含元素的內部陣列的指標 | 是 | 是 | - |
函式成員 | list<T> | forward list<T> |
---|---|---|
begin() - 返回開始迭代器 | 是 | 是 |
end() - 返回結束迭代器 | 是 | 是 |
rbegin() - 返回反向開始迭代器 | 是 | - |
rend() - 返回反向結束迭代器 | 是 | - |
cbegin() - 返回 const 開始結束迭代器 | 是 | 是 |
before_begin() - 返回一個指向第一個元素前一個位置的迭代器 | - | 是 |
cbefore_begin() - 返回一個指向第一個元素前一個位置的const迭代器 | - | 是 |
cend() - 返回 const 結束迭代器 | 是 | 是 |
crbegin() - 返回 const 反向開始迭代器 | 是 | - |
crend() - 返回 const 反向結束迭代器 | 是 | - |
assign() - 用新元素替換原有內容 | 是 | 是 |
operator=() - 複製同類型容器的元素,或者用初始化列表替換現有內容 | 是 | 是 |
size() - 返回實際元素個數 | 是 | - |
max_size() - 返回元素個數的最大值 | 是 | 是 |
resize() - 改變實際元素的個數 | 是 | 是 |
empty() - 返回 true,如果容器中沒有元素的話 | 是 | 是 |
from() - 返回第一個元素的引用 | 是 | 是 |
back() - 返回最後一個元素的引用 | 是 | - |
push_back() - 在序列的潘部新增一個元素 | 是 | - |
push_front() - 在序列的起始位置新增一個元素 | 是 | 是 |
emplace() - 在指矩位置直接生成一個元素 | 是 | - |
emplace_after() - 在指定位置的後面直接生成一個元素 | - | 是 |
emplace_back() - 在序列尾部生成一個元素 | 是 | - |
cmplacc_front() - 在序列的起始位生成一個元索 | 是 | 是 |
insert() - 在指定的位置插入一個或多個元素 | 是 | - |
insert_after() - 在指定位置的後面插入一個或多個元素 | - | 是 |
pop_back() - 移除序列尾部的元素 | 是 | - |
pop_front() - 移除序列頭部的元素 | 是 | 是 |
reverse()-反向元素的順序 | 是 | 是 |
erase() - 移除指定位置的一個元素或一段元素 | 是 | - |
erase_after() - 移除指定位 1;後面的一個元素或一段元素 | - | 是 |
remove() - 移除所苻和引數匹配的元素 | 是 | 是 |
remove_if() - 移除滿足一元函式條件的所有元素 | 是 | 是 |
unique() - 移除所有連續重複的元素 | 是 | 是 |
clear() - 移除所有的元素,容器大小變為 0 | 是 | 是 |
swap() - 交換兩個容器的所有元素 | 是 | 是 |
sort() - 對元素進行排序 | 是 | 是 |
merge() - 合併兩個有序容器 | 是 | 是 |
splice() - 移動指定位置前面的所有元素到另一個同類型的 list 中 | 是 | - |
splice_after() - 移動指定位置後面的所有元素到另一個同類型的 list 中 | - | 是 |
6.常見的容器介面卡?
容器介面卡是一個封裝了序列容器的類模板,它在一般序列容器的基礎上提供了一些不同的功能。之所以稱作介面卡類,是因為它可以通過適配容器現有的介面來提供不同的功能。
這裡有 3 種容器介面卡:
- stack<T>:是一個封裝了 deque<T> 容器的介面卡類模板,預設實現的是一個後入先出(Last-In-First-Out,LIFO)的壓入棧。stack<T> 模板定義在標頭檔案 stack 中。
- queue<T>:是一個封裝了 deque<T> 容器的介面卡類模板,預設實現的是一個先入先出(First-In-First-Out,LIFO)的佇列。可以為它指定一個符合確定條件的基礎容器。queue<T> 模板定義在標頭檔案 queue 中。
- priority_queue<T>:是一個封裝了 vector<T> 容器的介面卡類模板,預設實現的是一個會對元素排序,從而保證最大元素總在佇列最前面的佇列。priority_queue<T> 模板定義在標頭檔案 queue 中。
7.stack堆疊操作
stack<T>容器介面卡中的資料是以 LIFO 的方式組織的,和其他序列容器相比,stack 是一類儲存機制簡單、所提供操作較少的容器。下面是 stack 容器可以提供的一套完整操作:
top():返回一個棧頂元素的引用,型別為 T&。如果棧為空,返回值未定義。
push(const T& obj):可以將物件副本壓入棧頂。這是通過呼叫底層容器的 push_back() 函式完成的。
push(T&& obj):以移動物件的方式將物件壓入棧頂。這是通過呼叫底層容器的有右值引用引數的 push_back() 函式完成的。
pop():彈出棧頂元素。
size():返回棧中元素的個數。
empty():在棧中沒有元素的情況下返回 true。
emplace():用傳入的引數呼叫建構函式,在棧頂生成物件。
swap(stack<T> & other_stack):將當前棧中的元素和引數中的元素交換。引數所包含元素的型別必須和當前棧的相同。對於 stack 物件有一個特例化的全域性函式 swap() 可以使用。
8. queue(STL queue)用法
只能訪問 queue<T> 容器介面卡的第一個和最後一個元素。只能在容器的末尾新增新元素,只能從頭部移除元素。
queue操作:
queue 和 stack 有一些成員函式相似,但在一些情況下,工作方式有些不同:
(1)front():返回 queue 中第一個元素的引用。如果 queue 是常量,就返回一個常引用;如果 queue 為空,返回值是未定義的。
(2)back():返回 queue 中最後一個元素的引用。如果 queue 是常量,就返回一個常引用;如果 queue 為空,返回值是未定義的。
(3)push(const T& obj):在 queue 的尾部新增一個元素的副本。這是通過呼叫底層容器的成員函式 push_back() 來完成的。
(4)push(T&& obj):以移動的方式在 queue 的尾部新增元素。這是通過呼叫底層容器的具有右值引用引數的成員函式 push_back() 來完成的。
(5)pop():刪除 queue 中的第一個元素。
(6)size():返回 queue 中元素的個數。
(7)empty():如果 queue 中沒有元素的話,返回 true。
(8)emplace():用傳給 emplace() 的引數呼叫 T 的建構函式,在 queue 的尾部生成物件。
(9)swap(queue<T> &other_q):將當前 queue 中的元素和引數 queue 中的元素交換。它們需要包含相同型別的元素。也可以呼叫全域性函式模板 swap() 來完成同樣的操作。
9.C++序列容器儲存智慧指標
通常用容器儲存指標比儲存物件更好,而且大多數時候,儲存智慧指標比原生指標好。下面是一些原因:
在容器中儲存指標需要複製指標而不是它所指向的物件。複製指標通常比複製物件快。
(1)在容器中儲存指標可以得到多型性。存放元素基類指標的容器也可以儲存其派生型別的指標。當要處理有共同基類的任意物件序列時,這種功能是非常有用的。應用這一特性的一個常見示例是展示一個含有直線、曲線和幾何形狀的物件序列。
(2)對指標容器的內容進行排序的速度要比對物件排序快;因為只需要移動指標,不需要移動物件。
(3)儲存智慧指標要比儲存原生指標安全,因為在物件不再被引用時,自由儲存區的物件會被自動刪除。這樣就不會產生記憶體洩漏。不指向任何物件的指標預設為 nullptr。
10.各容器的實現原理
vector 擁有一段連續的記憶體空間
list 就是資料結構中的雙向連結串列
deque 的動態陣列首尾都開放
set 有序的容器,紅黑樹的平衡二叉檢索樹的資料結構
multiset 紅黑樹實現的,set插入的元素不能相同,但是multiset可以相同。
map 鍵不能重複,紅黑樹實現的,
mtltimap 紅黑樹實現的,允許鍵有重複
這一章感覺做成了字典,不應該這樣的!所以不再新增內容!這部分主要是各個容器的操作函式和演算法函式較多,感覺用的時候查一查。提供學習的地址:http://c.biancheng.net/stl/algorithms/