STL 是什麼?
STL 簡單來說,就是容器,裝資料的容器。
之前,我們學習過的容器只有array而已,array的缺點有幾個:
- 不能改變大小
- 不能從前面插入元素(從前面插等於將整個陣列往後,可以想像,這超慢)
- 不能自動排序好元素(也就是,插入一個數字後要重新排序很慢)
但STL裡的容器很特別,他有:
- 可以改變陣列大小的 vector
- 可以從前方插入或移除元素的 deque、queue
- 可以邊插入邊移除,一邊很快的排序的 set、map,以及priority_queue
- 可以對 bool 陣列進行位元運算,大幅加快速度的 bitset
因此,學習使用 STL,能讓你的實力更上一層樓!
宣告
STL 的語法大致相近。
1 | vector<int> v; |
其中,想特別講一下<>。這是 C++ 裡的 template 功能,要用什麼型態就放在裡面,非常自由。想用二維陣列的話,就在 vector 裡面再包一個 vector 吧!
迭代器(iterator)
STL 中,有一個新的概念:迭代器。
以往,如果要找到一個陣列 arr 開頭的位置,我們可以直接寫 arr,因為 arr 本身其實只是一個指標而已。要找到陣列第 N 項的位置,就是 arr+N,因為記憶體在陣列裡是連續的,所以可以直接加,但這些在 STL 中是做不到的。
假設你宣告了一個 vector 名為 v,那這個 v 在之後的程式中,不是代表記憶體,而是整個容器。
因此若需要得到 v 開頭的位置,要寫: v.begin()。v 結束的位置要寫 v.end()。在 set 與 map 中將會有迭代器的進階應用。
成員函式(member function)
1 | struct my_struct{ |
像是之前的 struct,假設我要得到 s 裡的 a 這個值,要寫 s.a。
STL 中也有類似的概念,但是,裡面包的是函式!比如剛剛的 .begin(),呼叫它,得到的回傳值就是這個容器的開始位置。
因為是函式,所以會有()的存在。有些函式需要傳入參數,就像正常使用函式那樣,在()中傳入就可以了。
常見的成員函式有:
- .begin():容器的開始位置
- .end() :容器的結束位置
- .size() :回傳容器大小,型態是 unsigned int,拿來跟 int 比較(.size() > 5)沒有問題,但編譯器會噴警告。拿來進行運算則存在 overflow 風險(<0的時候,unsigned int 就 overflow)。
- .empty() :回傳容器是否為空,型態是 bool,盡量多使用 .empty(),而非 .size() == 0。
- (vector).push_back(x):在後方加入元素 x
- (vector).pop_back():移除最後方元素
- (set map).insert(x):加入元素 x
總結
STL 超好用的!
從下一章開始,將會一個一個介紹常用的 STL,請不知道是否存在的長期讀者們稍等一下!