[GeekBand] STL與泛型編程-2

容器適配器

Stack
stack 是一種先進后出(First In Last Out)的數(shù)據(jù)結構秘噪,只有一個出口犁珠。stack 支持的操作:增加元素(push)、移除元素(pop)盼樟、獲取最頂端元素(top)同窘。stack 無遍歷操作,無 iterator附井。使用時必須包含 <stack> 頭文件讨越。stack 底層以容器 Deque 實現(xiàn),因為 stack 修改了 deque 的接口永毅,使其以另一種風貌出現(xiàn)把跨,故可稱其為適配器(adapter),具體而言就是容器適配器卷雕。另外也可以 list 作為 stack 的底層容器节猿。

// 摘自《STL源碼剖析》
// file: 4stack-test.cpp
#include <stack>
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    stack<int, list<int> > istack;
    istack.push(1);
    istack.push(3);
    istack.push(5);
    istack.push(7);
    cout << istack.size() << endl;  // 4 
    cout << istack.top() << endl;   // 7
    istack.pop(); cout << istack.top() << endl;  // 5
    istack.pop(); cout << istack.top() << endl;  // 3
    istack.pop(); cout << istack.top() << endl;  // 1
    cout << istack.size() << endl;  // 1 
}

Queue
queue 是一種先進后出(First In First Out)的數(shù)據(jù)結構票从,有兩個出口漫雕。queue 支持的操作:增加元素(push)、移除元素(pop)峰鄙、獲取最前段元素(front)浸间、獲取最后的元素(back)。queue 無遍歷操作吟榴,無 iterator魁蒜。使用時必須包含 <queue> 頭文件。queue 底層以容器 deque 實現(xiàn)吩翻,也是一種容器適配器兜看。同樣可以使用 list 作為 queue 的底層容器。

// 摘自《STL源碼剖析》
// file: 4queue-test.cpp
#include <queue>
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    queue<int, list<int> > iqueue;
    iqueue.push(1);
    iqueue.push(3);
    iqueue.push(5);
    iqueue.push(7);

    cout << iqueue.size() << endl;  //4
    cout << iqueue.front() << endl;  // 1

    iqueue.pop(); cout << iqueue.front() << endl;  // 3
    iqueue.pop(); cout << iqueue.front() << endl;  // 5
    iqueue.pop(); cout << iqueue.front() << endl;  // 7
    cout << iqueue.size() << endl;  // 1
}

Priority_queue
priority_queue 是一個帶有權值觀念的 queue狭瞎,其內(nèi)的元素自動依照元素的權值排列细移,權值最高者,排在最前面熊锭。priority_queue 以 max-heap 實現(xiàn)其依據(jù)權值高低自動遞減排序的特性弧轧,而 max-heap 底層則以容器 vector 實現(xiàn)。

// 摘自《STL源碼剖析》
// file: 4pqueue-test.cpp
#include <queue>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    int ia[9] = {0, 1, 2, 3, 4, 8, 9, 3, 5};
    priority_queue<int> ipq(ia, ia + 9);
    cout << "size = " << ipq.size() << endl;  // size = 9
    for (int i = 0; i < ipq.size(); ++i) {
        cout << ipq.top() << ' ';  // 9 9 9 9 9 9 9 9 9        
    }
    cout << endl;
    
    while (!ipq.empty()) {
        cout << ipq.top() << ' ';  // 9 8 5 4 3 3 2 1 0
        ipq.pop();
    }
    cout << endl;
}

關聯(lián)容器

Set
set 是一種關聯(lián)容器碗殷,存儲的對象既是鍵值(Key) 又是實值(Value)精绎。

  • 不允許有重復的 Key;
  • 所有元素根據(jù)鍵值自動被排序;
  • 存儲的對象必須具備可排序性锌妻,默認采用less定義排序行為代乃,存儲對象必須具備 operator < 行為;
  • 不能通過迭代器改變對象成員中真正的 Key仿粹;
  • set 以 RB-tree 為底層機制襟己;
  • 相關算法有交集(set_intersection)引谜、聯(lián)集(set_union)、差集(set_difference)擎浴、對稱差集(set_symmetric_difference)员咽。
template < class T, 
             class Compare = less<T>, 
             class Alloc = allocator<T> >  
class set {
    ...
};

Multiset
multiset 與 set 的特性及用法與 set 相同,差別在于 multiset 允許鍵值重復贮预,因此其插入操作采用的底層機制是 RB-tree 的 insert_equal()贝室,而 set中的插入操作則采用 RB-tree 的 insert_unique()。

Map
map 是一種關聯(lián)容器仿吞,存儲的對象是鍵值與實值構成的數(shù)據(jù)對(Key/Value pair)滑频。pair 的第一元素為 key,第二元素為 value唤冈。

  • 不允許有重復的 Key;
  • 所有元素根據(jù)鍵值自動被排序峡迷;
  • 存儲的對象必須具備可排序性,默認采用less定義排序行為你虹,存儲對象必須具備 operator < 行為绘搞;
  • 不能通過迭代器改變對象的 Key;
  • map 以 RB-tree 為底層機制傅物;
template < class Key, class T,                                       
           class Compare = less<Key>,                  
           class Alloc = allocator< pair<const Key, T> > > 
class map {
    ...
};

Multimap
multimap 與 map 的特性和用法與 map 相同夯辖,差別在于 multimap 允許鍵值相同,因此其插入操作采用的底層機制是 RB-tree 的 insert_equal()董饰,而 map 中的插入操作則采用 RB-tree 的 insert_unique()蒿褂。

Unordered Set
unordered_set 容器中存儲的對象既是鍵值也是實值。元素的值是不可修改的卒暂,但可以刪除和插入啄栓。unordered_set內(nèi)部沒有像 set 那樣采用 RB-tree,元素不會按任何順序排序也祠,而是通過以鍵值為參數(shù)的 hash 函數(shù)生成的 hash 值將元素分組放置到各個桶(bucket)中昙楚,這樣就能通過鍵值快速地訪問各個對應的元素(平均耗時為一個常量,即時間復雜度為O(1))齿坷。

  • 在訪問容器中的某個元素時桂肌,unordered_set 容器比set 容器高效,而在迭代容器元素的某個子集時永淌,前者比后者稍微低效了一點崎场;
  • unordered_set 容器支持正向迭代。
template < class Key,                      
           class Hash = hash<Key>,         
           class Pred = equal_to<Key>,       
           class Alloc = allocator<Key> > 
class unordered_set {
    ...
};

Unordered Map
在 unordered_map 容器像 map 一樣存儲 key/value 對遂蛀,但內(nèi)部并未像 map 那樣采用 RB-tree谭跨,元素之間不會按任何順序排列。 unordered_map 通過以鍵值 key 為參數(shù)的 hash 函數(shù)得到 hash 值,將元素分組放置到各個桶(bucket)中螃宙,這樣就能通過鍵值快速地訪問各個對應的元素(平均耗時為一個常量蛮瞄,即時間復雜度為O(1))。

  • 在訪問容器中的某個元素時谆扎,unordered_map 容器比 map 容器高效挂捅,而在迭代容器元素的某個子集時,前者比后者稍微低效了一點堂湖;
  • unordered_map 實現(xiàn)了直接訪問操作符 []闲先,使得可以通過鍵值 key 直接訪問被映射的實值 value;
  • unordered_map容器支持正向迭代无蜂。
template < class Key,                                    
           class T,                                    
           class Hash = hash<Key>,                     
           class Pred = equal_to<Key>,                
           class Alloc = allocator< pair<const Key, T> > >
class unordered_map {
    ...
};

仿函數(shù)適配器

**bind1st 與 bind2nd **
bind1st和bind2nd函數(shù)用于將一個二元算子(binary functor伺糠,bf)轉換成一元算子(unary functor,uf)斥季。它們需要兩個參數(shù):要轉換的二元算子 bf 和一個值 v训桶。

template <class _Fn2, class _Ty>
inline binder1st<_Fn2> bind1st(const _Fn2& Func, const _Ty& _Left)
{
    typename _Fn2::first_argument_type _Val(_Left);
    return (binder1st<_Fn>(_Func, _Val));
}

mem_fun 與 mem_fun_ref
對于函數(shù) f 以及對象 obj,在 obj 上調(diào)用 f 的形式可以有3種:

f(obj)      // f 是全局函數(shù)酣倾,非 obj 成員函數(shù)
obj.f       // f 是 obj 的成員函數(shù)舵揭,obj 非指針
obj->f      // f 是 obj 的成員函數(shù),obj 是指針

為了使 obj 的成員函數(shù)能夠以第一種形式被調(diào)用灶挟,則需要使用 mem_fun 或 mem_fun_ref琉朽。當 obj 為指針時毒租,將 obj 成員函數(shù)的引用作為參數(shù)傳遞給 mem_fun()稚铣,當 obj 非指針時,將obj成員函數(shù)的引用作為參數(shù)傳遞給 mem_fun_ref()墅垮。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惕医,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子算色,更是在濱河造成了極大的恐慌抬伺,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灾梦,死亡現(xiàn)場離奇詭異峡钓,居然都是意外死亡,警方通過查閱死者的電腦和手機若河,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門能岩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人萧福,你說我怎么就攤上這事拉鹃。” “怎么了?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵膏燕,是天一觀的道長钥屈。 經(jīng)常有香客問我,道長坝辫,這世上最難降的妖魔是什么篷就? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮近忙,結果婚禮上腻脏,老公的妹妹穿的比我還像新娘。我一直安慰自己银锻,他們只是感情好永品,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著击纬,像睡著了一般鼎姐。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上更振,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天炕桨,我揣著相機與錄音,去河邊找鬼肯腕。 笑死献宫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的实撒。 我是一名探鬼主播姊途,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼知态!你這毒婦竟也來了捷兰?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤负敏,失蹤者是張志新(化名)和其女友劉穎贡茅,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體其做,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡顶考,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了妖泄。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片驹沿。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖浮庐,靈堂內(nèi)的尸體忽然破棺而出甚负,到底是詐尸還是另有隱情柬焕,我是刑警寧澤,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布梭域,位于F島的核電站斑举,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏病涨。R本人自食惡果不足惜富玷,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望既穆。 院中可真熱鬧赎懦,春花似錦、人聲如沸幻工。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽囊颅。三九已至当悔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間踢代,已是汗流浹背盲憎。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留胳挎,地道東北人饼疙。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像慕爬,于是被迫代替她去往敵國和親窑眯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容