STL和c++標準庫 標準模板庫STL部分包含在C++標準庫中的軟體庫。 c++標準庫:即以std::開頭,但是部分編譯器廠商也會把STL的內容放在std:: namespace裡面 由於一個常見的誤解,您可能會將C++標準庫視為“STL”,或者將工具鏈中C++標準庫的實現部分視為“STL實現”。 ...
STL和c++標準庫
標準模板庫STL部分包含在C++標準庫中的軟體庫。
c++標準庫:即以std::開頭,但是部分編譯器廠商也會把STL的內容放在std:: namespace裡面
由於一個常見的誤解,您可能會將C++標準庫視為“STL”,或者將工具鏈中C++標準庫的實現部分視為“STL實現”。
事實並非如此。
MSVC ++和GCC(作為編譯器特定的擴展實現)都將其放在std
命名空間中也是非常可惜的,這不僅具有高度誤導性,而且根據標準也是非法的。
為什麼c++的名詞會這麼混亂?
因為c++委員會制定標準,各家編譯器廠商實現標準(gcc,msvc)
vector
類似於C#中的List,長度會自動擴容(2倍擴容),普通的數組需要初始化長度。
vector容器是支持隨機訪問的,即可以像數組一樣用[]來取值。但不是所有的STL容器都有這個特性!
用法 | 作用 |
---|---|
vec.begin(),vec.end() | 返回vector的首、尾迭代器 |
vec.front(),vec.back() | 返回vector的首、尾元素 |
vec.push_back() | 從vector末尾加入一個元素 |
vec.size() | 返回vector當前的長度(大小) |
vec.pop_back() | 從vector末尾刪除一個元素 |
vec.empty() | 返回vector是否為空,1為空、0不為空 |
vec.clear() | 清空vector |
queue隊列
先進先出,沒有clear,也不支持遍歷
文檔:std::queue - cppreference.com
用法 | 作用 |
---|---|
q.front(),q.back() | 返回queue的首、尾元素 |
q.push() | 從queue末尾加入一個元素 |
q.size() | 返回queue當前的長度(大小) |
q.pop() | 刪除首個元素 |
q.empty() | 返回queue是否為空,1為空、0不為空 |
stack
後進先出
用法 | 作用 |
---|---|
st.top() | 返回stack的棧頂元素 |
st.push() | 從stack棧頂加入一個元素 |
st.size() | 返回stack當前的長度(大小) |
st.pop() | 從stack棧頂彈出一個元素 |
st.empty() | 返回stack是否為空,1為空、0不為空 |
string 容器
string是C++風格的字元串,而string本質上是一個類
string和char * 區別:
- char * 是一個指針
- string是一個類,類內部封裝了
char*
,管理這個字元串,是一個char*型的容器
string特點:
string 類內部封裝了很多成員方法,例如:查找find,拷貝copy,刪除delete 替換replace,插入insert
string管理char*所分配的記憶體,不用擔心複製越界和取值越界等,由類內部進行負責
導入:#include
<string>
// 註意這裡不是string.h,string.h是C字元串頭文件
用法 | 說明 |
---|---|
int find(const string& str, int pos = 0) const; | 查找str第一次出現位置,從pos開始查找 |
int compare(const string &s) const; | 字元串比較是按字元的ASCII碼進行對比,返回值:0:=,1:>,-1:< |
string& insert(int pos, const string& str); | 插入字元串 |
string& erase(int pos, int n = npos); | 刪除從Pos開始的n個字元 |
char& operator[](int n);char& at(int n); | 獲取單個字元 |
string substr(int pos = 0, int n = npos) const; | 返回由pos開始的n個字元組成的字元串 |
參考資料:
\0
:是一個空字元,在cout中輸出是空的,表示字元串的結束
string轉成char*
string str;
const char *c = str.c_str();
char*轉成string
string str;
const char *pc = "Hello World";
str = pc;
char[]轉成string
char ch [] = "ABCDEFG";
string str(ch); //也可string str = ch;
print中註意事項
string str="hello";
printf(“%s\n”, str); //此處出現錯誤的輸出
cout<<str<<endl;
用printf(“%s”,str);輸出是會出問題的。這是因為“%s”要求後面的對象的首地址。但是string不是這樣的一個類型,若一定要printf輸出。那麼可以加上.c_str()。
map
map使用紅黑樹實現。查找時間在O(lg(n))-O(2*log(n))之間,構建map花費的時間比較長
c++中的map是有序的?我使用過其它語言map都是無序的,經測試確實是有序的
map中獲取某個值的方法:find,然後再通過first,second來取key和value
map和multimap應該使用那一個?
在項目代碼中multimap會多一些
hasp_map
hash_map是 STL 的一部分,但不是標準C++ (C++11) 的一部分。在標準C++中,有一個名為“std::unordered_map”的功能類似unordered_map實現:http://www.cplusplus.com/reference/unordered_map/unordered_map/
C++11 引入了 std::unordered_map
和hash_map沒有什麼不同。
參考資料:https://stackoverflow.com/questions/5908581/is-hash-map-part-of-the-stl
該用hash_map還是map?
hash_map 查找速度會比map快,而且查找速度基本和數據數據量大小,屬於常數級別;而map的查找速度是log(n)級別。並不一定常數就比log(n)小,hash還有hash函數的耗時,明白了吧,如果你考慮效率,特別是在元素達到一定數量級時,考慮考慮hash_map。
但若你對記憶體使用特別嚴格,希望程式儘可能少消耗記憶體,那麼一定要小心,hash_map可能會讓你陷入尷尬,特別是當你的hash_map對象特別多時,你就更無法控制了,而且hash_map的構造速度較慢。
來源:C++ map和hashmap用法_qq_33216029的博客-CSDN博客_c++ hashmap
set
set容器,有點像C#中的hashset,裡面的元素是唯一不重覆的,且內部排好序(升序排列)。
set容器自動有序和快速添加、刪除的性質是由其內部實現:紅黑樹(平衡樹的一種)
用法 | 作用 |
---|---|
s.empty() | 當前集合是否為空,是返回1,否則返回0. |
s.size() | 當前集合的元素個數 |
s.clear() | 清空當前集合 |
s.begin(),s.end(); | 返回集合的首尾迭代器。註意是迭代器。我們可以把迭代器理解為數組的下標。但其實迭代器是一種指針 |
s.insert(k) | 向集合中加入元素k |
s.erase(k) | 刪除集合中元素k |
s.find(k) | 返回集合中指向元素k的迭代器。如果不存在這個元素,就返回s.end() |
deque
用法 | 作用 |
---|---|
q.begin(),q.end() | 返回deque的首、尾迭代器 |
q.front(),q.back() | 返回deque的首、尾元素 |
q.push_back() | 從隊尾入隊一個元素 |
q.push_front() | 從隊頭入隊一個元素 |
q.pop_back() | 從隊尾出隊一個元素 |
q.pop_front() | 從隊頭出隊一個元素 |
q.clear() | 清空隊列 |
deque的特點是雙端進出,即處於雙端隊列中的元素既可以從隊首進/出隊,也可以從隊尾進/出隊,它是線性容器。
deque比queue更優秀的一個性質是它支持隨機訪問,即可以像數組下標一樣取出其中的一個元素。
c++所有容器表格
表格數據來源:容器庫 - cppreference.com
參考資料
史上最全的各種C++ STL容器全解析 - Seaway-Fu - 博客園 (cnblogs.com)