C++ STL容器之 map

C++ STL容器之 map

map 是一種有序無重複的關聯容器。

關聯容器與順序容器不同,他們的元素是按照關鍵字來保存和訪問的,而順序元素是按照它們在容器中的位置保存和訪問的。

map保存的是一種 key - value 的pair對象,其中 key 是關鍵字,value 是關鍵字對應的值。通過 key找到對應的 value。map中按照 key的大小升序排列pair對象。

typedef pair<const Key, T> value_type

其中key 是 const的,即不可以改變map中的key。

在map中定位特定的元素比 unordered_map 要慢,因爲在 map中需要根據 key的大小進行順序查找。

但是在map中允許直接選取一定範圍的元素。

map在底層通常用二叉搜索樹實現。

template < class Key,                                     // map::關鍵字類型
           class T,                                       // map::值類型
           class Compare = less<Key>,                     // map::關鍵字比較函數
           class Alloc = allocator<pair<const Key,T> >    // map::allocator類
           > class map;

模板參數的第三個 class Compare = less<Key> 是一種比較函數

通過這個比較函數,map能比較兩個不同的 key值的大小關係,及是否相等。默認採用 less<Key>, 即 Key 類型的 "<"操作符。

如果 Key類型沒有"<"操作符的定義,則需要提供一個自定義比較函數的函數指針,來作爲Compare函數。

構造函數

  (1) 默認構造: map<Key, value> m;  構造一個空的map,注意,必要時要給出模板參數中的 Compare。需要時給出 Alloc

  (2) 範圍構造: map<key, value> m(iterator first, iterator last);  將迭代器[frist, last)範圍內的元素填入map中

  (3) 拷貝構造: map<key, value> m(cosnt map& m2);  用m2構造m

  (4) 初始化列表構造: map<key, value> m(initializer_list<value_type> il)

             由於map 的 value_type 是 pair類型,所以要構造成pair作爲列表,這是三種構造 pair的方式

             map<key, value> m{{key k1, value v1},{k2, v2}, ...}  // 通過 {}構造 pair

             map<key, value> m{make_pair(key k1, value v1), make_pair(k2, v2), ...}  // 通過 make_pair() 函數構造 pair

             map<key, value> m{pair<key, value>(k1, v1), pair<key, value>(k2, v2), ...}  // 通過類型轉換構造 pair

賦值操作符=

  map& operator= (const map& x)   // map賦值

  map& operator= (map&& x)    // 不懂

  map& operator= (initializer_list<value_type> il)  // 參數列表賦值

迭代器

  begin, end, rbegin, rend

  cbegin, cend, crbegin, crend

  map 的迭代器支持 ++, -- 操作,但是不支持 +i 操作。

  注意 map中是根據 key的值來排列元素的位置的,所以通過迭代器遍歷出來的結果順序,可能和插入值的順序不同。

  另外對 map的迭代器解引用的結果是得到一個 pair類型的對象。它有兩個共有成員 first, second。first保存 key的值,second 保存value的值。

  由於map的 key 是 const的,所以得到的 pair 的first 也是const 的。

成員函數

  容量

    empty()  // 如果map 爲空,返回true。否則返回 false

          // bool empty() const noexcept;

    size()    // 返回map 中元素的大小,即 key-value 的個數

          // size_type size() const noexcept;

    max_size()    // 返回由於存儲空間的限制,map有可能包含的最大元素數。但不保證一定能達到這個數量,有可能在中途申請空間失敗。

             // size_type max_size() const noexcept;

  元素訪問

    操作符[]  // m[k] 返回map 中 Key爲 k的元素的value的引用。

          // 如果 k不存在,那麼將會插入一個 key爲 k的元素,並返回其默認 value。

          // []操作總會將 map的大小 +1

          // 注意,對於map,解引用迭代器得到 pair,操作符[]得到 value

    at()    // m.at(k) 返回map中Key爲k的元素的value的引用。

          // 如果k不存在,拋一個 out_of_range 異常。

          // 使用 at 不會添加元素,不會增加 map的大小

  修改

    insert  插入

         (1) pair<iterator, bool> insert(const pair<key, value> &val);

           // 單個值插入,參數爲 pair類型,first 爲 key, second爲 value

           // 返回值也是一個 pair,first爲插入後的 iterator,second 爲bool類型, true表示插入成功,false 表示插入失敗

           // 插入失敗是因爲 map 中已經有一個 key 與輸入相同。這次插入操作對map 不會有任何影響, 失敗時返回值的 first指向已有的key-value

         (2) iterator insert(const_iterator pos, const pair<key, value> &val);

            // 提示值插入

            // 從 pos 指定的位置開始查找 val應該插入的位置

            // 如果設定值合適,可以減少插入時做查找的時間

         (3) void insert(iterator first, iterator second);

            // 範圍插入,插入[first, second)範圍內的內容

         (4) void insert(initializer_list<value_type> il);

            // 初始化列表插入

    emplace  高效插入

          和 insert的主要區別在於,insert首先構造一個臨時 value_type對象,再copy到 map中。

          而emplace 是直接在map里根據參數構造 value_type對象。更高效。

          pair<iterator, bool> emplace(key k, value v);

          返回值與 insert情況相同。

    emplace_hint  提示位置的高效插入

          iterator emplace(const iterator pos, key k, value v);

          從pos開始查找應該插入的位置,其餘和 emplace相同。

    erase  刪除

          (1) iterator erase(const_iterator position);  // 刪除迭代器指向的內容, 函數返回 NULL

          (2) iterator erase(const_iterator first, const_iterator last);  // 刪除迭代器範圍內的內容,函數返回NULL

          (3) size_type erase(const key_type &k);   // 刪除 type 爲k的元素,返回刪除的數目。對於 map,成功刪除返回1,k不存在則返回0

          (4) 1,2中如果迭代器無效,會產生 undefined behavior

    swap  交換兩個 map對象的內容

          (1) void swap(map &x)

          (2) void swap(map &x1, map &x2)  // 非成員重載函數

    clear  清空一個容器的所有元素

          void clear() noexcept;

  操作

    find  查找

        在map中查找key 爲 k的元素,返回指向它的迭代器。若k不存在,返回 map::end.

        // iterator find(const key_type &k);

    count  計數

         統計map中 key爲k的元素的個數,對於map,返回值不是1(存在),就是0(不存在)

         // size_type count(const key_type &k) const;

    

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