c++的關聯容器入門(map and set)

目錄c++

C++的關聯容器主要是兩大類map和set算法

咱們知道談到C++容器時,咱們會說到 順序容器(Sequence containers),關聯容器(Associative containers),無序關聯容器(Unordered associative containers)以及容器適配器(Container adaptors),數據結構

另外,我相信,這些抽象的容器概念,應該是全部高級語言都有的。本文重點闡述關聯容器。函數

Associative containers implement sorted data structures that can be quickly searched (O(log n) complexity).測試

關聯容器實現了能夠快速搜索(O(log n)複雜度)的排序數據結構。ui

主要就是 set、map、multiset和multimap。.net

std::map

map is a sorted associative container that contains key-value pairs with unique keys. Keys are sorted by using the comparison function Compare. Search, removal, and insertion operations have logarithmic complexity. Maps are usually implemented as red-black trees。code

map是一個排序的關聯容器,它包含具備唯一鍵的鍵值對。經過使用Compare函數對鍵進行排序。搜索、刪除和插入操做具備對數複雜度。映射一般被實現爲紅黑樹對象

理解map須要理解鍵值對有序鍵值惟一以及對數級別的操做。blog

  • 鍵值對

    既然是關聯容器,那天然要關聯下,這裏的關聯就是key和value的關聯,經過std::map<string,string> mapStr;這樣,咱們就定義了一個key爲string ,value爲string的map。咱們能夠經過中括號直接給鍵值對賦值:

    mapStr["name"] = "lckfa";
    mapStr["sexuality"] = "male";

    事實上,map的底層是使用pair來實現的,std::pair是一個結構模板,它提供了一種將兩個異構對象存儲爲單個單元的方法。所以還可使用以下代碼完成上面的操做:

    pair<string,string> pair1("name","lckfa");
    pair<string,string> pair2("sexuality","male");
    mapStr.insert(pair1);
    mapStr.insert(pair2);
  • 有序

    爲了看看map是怎麼有序的,咱們先弄個打印函數出來

    template<typename Map>
    void print_map(Map& m){
        std::cout << "{ " ;
        for_each(m.begin(),m.end(),[&](Map::value_type& p){
            std::cout << p.first <<":"<<p.second<<' ';
        });
        std::cout << "}" ;
    }

    這個打印函數模板,能夠打印任何類型的map。這下不再擔憂map的類型改變了。還不會使用labmda表達式的,能夠去看個人另外一篇博文,另外value_type能夠理解爲pair,這裏和Map是一個類型。

    而後,咱們在以前的map裏新增一個鍵值對

    mapStr["sss"] = "sss";
    mapStr["aaa"] = "aaa";
    mapStr["bbv"] = "bbb";

    使用pair,而後insert也行。

    而後調用print_map函數,結果以下:

    { aaa:aaa bbv:bbb name:lckfa sexuality:male sss:sss }

    以上結果充分說明 map是按key的升序排列的。

    備註,若是你想自定義map的排序方式,能夠參考這裏

  • 鍵值惟一

    白話就是,這裏的key值老是惟一的,那麼讓咱們來驗證下,同時向map裏插入相同鍵值會發生什麼:

    mapStr["name"] = "lckfa";
    mapStr["sexuality"] = "male";
    mapStr["name"] = "mal9";

    打印結果:

    { name:mal9 sexuality:male }

    從結果可知,再從新設置某個key的value後,後一個會覆蓋前一個value。

  • 對數級別的複雜度操做

    這個就不展開了,有興趣的能夠了解一個紅黑樹

std::set

std::set is an associative container that contains a sorted set of unique objects of type Key. Sorting is done using the key comparison function Compare. Search, removal, and insertion operations have logarithmic complexity. Sets are usually implemented as red-black trees

set是一個關聯容器,它包含一組類型爲Key的已排序的唯一對象。排序是使用key的比較函數比較來完成的。搜索、刪除和插入操做具備對數複雜度。集合一般被實現爲紅黑樹。

和map同樣,除了map的鍵值對差別,set只有key,這樣的差別外,set和map再定義和使用上沒有很大的差別。一樣的set也具備 key惟一,有序,對數複雜度的特色,這裏使用一個統一的代碼說明下:

template<typename Set>
void print_set(Set& s){
    cout << "{ ";
    for_each(s.begin(),s.end(),[&](Set::key_type k){
        std::cout << k <<' ';
    });
    std::cout << "}" ;
}

std::set<int> setInt;
setInt.insert(4);
setInt.insert(2);
setInt.insert(5);
setInt.insert(2);

std::set<string> setStr;
setStr.insert("hello");
setStr.insert("set");
setStr.insert("world");
setStr.insert("set");
print_set(setInt);
print_set(setStr);

測試輸出結果:

{ 2 4 5 }{ hello set world }

由結果可知:set的key值也是惟一的,同時按升序排列,若是但願自定義排列,須要需改比較函數。

小結:本文初略的整理了map和set的基礎使用,說明了兩者的特性,key惟一,有序,算法對數級。僅僅能做爲初學者參考。

相關文章
相關標籤/搜索