1. 程式人生 > 其它 >11-2 關聯容器概述

11-2 關聯容器概述

目錄

11.2.1 定義關聯容器

//宣告空容器
map<string, size_t> word_count;
//列表初始化
set<string> exclude = {"the","and","or"};

map<string, string> authors = { {"John","James"},
                                {"Asten","Jane"},
                                {"Dikens","Charles"}};

初始化multimap或multiset

int main(){
    //定義一個有20個元素的vector,儲存0到9每個整數的兩個拷貝
    vector<int> ivec;
    for (vector<int>::size_type i = 0; i != 10; ++i){
        ivec.push_back (i) ;
        ivec.push_back(i); //每個數重複儲存一次
    }
    //iset包含來自ivec的不重複的元素;miset包含所有20個元素 
    set<int> iset(ivec.cbegin(), ivec.cend()) ;
    multiset<int> miset(ivec.cbegin(), ivec.cend());
    
    cout<< ivec.size () << endl; //打印出20
    cout<< iset.size ( ) <<endl; //打印出 10
    cout << miset.size () <<endl;//打印出20
    return 0;
}

11.2.2 關鍵字型別的要求

對於有序容器map,multimap,set,multiset,關鍵字型別必須定義元素比較的方法

傳遞給排序演算法的可呼叫物件(參見10.3.1節,第344頁)必須滿足與關聯容器中關鍵字一樣的型別要求

有序容器的關鍵字型別

可以向一個演算法提供我們自己定義的比較操作(參見10.3節,第344頁),與之類似,也可以提供自己定義的操作來代替關鍵字上的<運算子。

所提供的操作必須在關鍵字型別上定義一個嚴格弱序(strict weak ordering)。可以將嚴格弱序看作“小於等於”,雖然實際定義的操作可能是一個複雜的函式。無論我們怎樣定義比較函式,它必須具備如下基本性質:

  • 兩個關鍵字不能同時“小於等於”對方;如果k1“小於等於”k2,那麼k2絕不能“小於等於”k1。
  • 如果 k1“小於等於”k2,且k2“小於等於”k3,那麼k1必須“小於等於”k3。
  • 如果存在兩個關鍵字,任何一個都不“小於等於”另一個,那麼我們稱這兩個關鍵字是“等價”的。如果k1“等價於”k2,且k2“等價於”k3,那麼k1必須“等價於”k3。

在實際程式設計中,我們考慮的是一個型別是否定義了“行為正常”的<運算子,只要定義了,它就可以用作關鍵字型別

使用關鍵字型別的比較函式

假設一個類型別Sale_data未定義‘<’,此時我們可以自己定義一個比較函式傳給map,來建立一個Sale_data的map【否則無法建立】

//依照isbn排序
bool compareIsbn(const Sale_data &lhs, const Sale_data &rhs){
    return lhs.isbn()<rhs.isbn();
}

建立Sale_data的map:

//bookstore中多條記錄可以有相同的isbn
//bookstore中的元素以isbn順序進行排序
multiset<Sale_data, decltype(compareIsbn)*>
    bookstore(compareIsbn);

模板接受兩個引數,一個指定元素型別,一個函式指標

宣告時傳入函式指標compareIsbn

注:和陣列名錶示一個指標類似,函式名就代表函式指標

11.2.3 pair型別

宣告和初始化

定義在標頭檔案utility

有兩個資料成員first和second,必須提供兩個型別引數

pair<string, string> anon;   //儲存兩個string
pair<string, size_t> word_count; //一個string一個size_t

可以在宣告時直接初始化first和second成員:

pair<int, int> i_to_i{1,2};
cout<<i_to_i.first<<" "<<i_to_i.second<<endl;
//輸出:1 2

支援的操作

建立pair物件的函式

函式可以返回pair物件

pair<string, int> process(vector<string> &v){
    if(!v.empty())
        return
        //構造一個pair並返回其拷貝
        pair<string, int>(v.back(), v.back().size());
    else
        //構造空pair並返回其拷貝
        return pair<string, int>();
}

除了直接定義外,還可以用make_pair來生成pair物件:

if(!v.empty())
    return make_pair(v.back(), v.back().size());

新標準允許在返回pair時直接進行列表初始化

if(!v.empty())
    return {v.back(), v.back().size()};