C++ primer 第五版個人筆記 第十一章 關聯容器

11.1 使用關聯容器

  1. 關聯容器map爲空時,新創建一個元素的鍵對應的值默認初始化爲0;
  2. 統計一個元素是否在set中有兩種寫法:
    myset.find(target)==myset.end();  //未找到
    myset.count(target)==0;            //未找到

     

  3. 對於有序容器(map,multimap,set,multiset),關鍵字類型必須定義元素比較的方法,默認情況下,標準庫使用關鍵字類型的<運算符來比較兩個關鍵字 ;

  4.  

    當關聯容器的元素爲自定義的類類型時,我們應該定義一個比較函數,這時候在關聯容器的元素類型尖括號裏必須提供兩個類型:關鍵字類型和比較操作類型(應該是一種函數指針類型),注意下例中使用decltype來指出要使用一個給定函數類型的指針。用compareIsbn來初始化bookstore對象,表示當我們向bookstore添加元素時,通過調用compareIsbn來爲這些元素排序;

     

     

    bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
    {
        return lhs.isbn()<rhs.isbn();
    }
    // 定義sales_data類的比較函數
    
    multiset<Sales_data, decltype(compareIsbn)*> bookstore(compareIsbn);
    // 定義multiset容器,其中元素類型爲Sales_data, 比較函數爲compareIsbn

     

11.2 關聯容器概述

  1. pair類型的構造方法,功能操作,詳見380頁;
  2. 練習11.12
    int main()
    {
    	vector<pair<string, int>> vec;
    	pair<string, int>temp;
    	while (cin >> temp.first >> temp.second)
    	{
    		vec.push_back(temp);
    	}
    	for (auto pir : vec)
    	{
    		cout << pir.first << " " << pir.second << endl;
    	}
    	return 0;
    }
     

11.3 關聯容器操作

  1. 當解引用一個關聯容器迭代器時,會得到一個類型爲容器的value_type的值的引用,三種關聯容器的類型別名(key_type, mapped_type, value_type)適用的容器見381頁;對於map而言,value_type是一個pair類型,其first成員保持const的關鍵字,second成員你保存值;;
  2. set的迭代器是const的,只允許讀set的元素,map只能讀key元素;
  3. 當使用一個迭代器遍歷一個map/multimap/set/multiset時,迭代器按照關鍵字升序遍歷元素;
  4. 關聯容器通常不使用泛型算法,因爲這類算法通常需要向元素寫入值,而set類型中的元素是const的,map中的元素是pair,pair的第一個成員也是const的;實際編程中,如果真要對一個關聯容器使用算法,要麼是將它當做一個原序列(如使用copy),要麼是當一個目的位置;
  5. 關聯容器通常使用insert函數進行插入操作,insert有兩個版本,分別接受一對迭代器(a.begin(),a.end()),或者一個初始化列表({arg1,arg2});map進行insert時要記住元素的類型是pair,插入map的4種方法如下:
    mymap.insert({arg1,arg2}); //初始化列表
    mymap.insert(make_pair(arg1,arg2)); //make_pair函數構造pair對象
    mymap.insert(pair<t1,t2>(arg1,arg2)); //構造函數構造臨時pair對象
    mymap.insert(map<t1,t2>::value_type(arg1,arg2)) //map的value_type爲pair,此處也是構造臨時對象

     

  6. insert(或emplace)返回的值依賴於容器類型和參數,對於不包含重複關鍵字的容器,添加單一元素的insert和emplace版本返回一個pair,first成員是一個迭代器指向具有給定關鍵字的元素,second成員是一個bool值指出元素是插入成功還是已經存在於容器中(false);

  7. 關聯容器定義了三個版本的erase用來刪除元素,與順序容器類似,指定元素刪除,函數返回void;一個額外的只有關聯容器有的erase操作,接受一個Key_type參數,刪除所有匹配給定關鍵字的元素(如果存在的話),返回實際刪除的元素的數量;詳細見387頁;

  8.  對於multimap或者unordered_multimap不能進行下標操作,因爲可能一個key對應多個value,map的下標運算符接受一個索引(即一個關鍵字)來獲取與此關鍵字相關聯的值;如果關鍵字並不在map中,會爲它創造一個元素並插入到map中,關聯值將進行值初始化;由於下標運算符可能插入一個新的元素,所以只可以對非const的map使用下標操作;

  9.  

    通常情況下,解引用一個迭代器所返回的類型與下標運算符返回的類型是一樣的,但對map而言,下標操作返回一個mapped_type對象;解引用時返回一個value_type對象(pair);與其他下標運算符相同的是,map的下標運算符返回一個左值,既可讀也可寫;

  10. multimap和multiset中使用lower_bound, upper_bound函數可以找到目標元素的範圍,用法跟equal_range相同

11.4 無序容器

  1. 如果關鍵字類型固有就是無需的,或者性能測試發現問題可以用哈希技術解決,就可以使用無序容器(unordered_);
  2. 無序容器在存儲上組織爲一組桶,每個桶保存另個或多個元素,無序容器使用一個哈希函數將元素映射到桶,無序容器的性能依賴於哈希函數的質量和桶的數量和大小;
  3. 管理桶的重載hash函數和比較函數,詳見396頁;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章