C++ map,STL map詳解

2020-07-16 10:04:24
map 是關聯容器的一種,map 的每個元素都分為關鍵字和值兩部分,容器中的元素是按關鍵字排序的,並且不允許有多個元素的關鍵字相同。

注意,不能直接修改 map 容器中的關鍵字。因為 map 中的元素是按照關鍵字排序的,當關鍵字被修改後,容器並不會自動重新調整順序,於是容器的有序性就會被破壞,再在其上進行查詢等操作就會得到錯誤的結果。

要使用 map,必須包含標頭檔案 <map>。map 的定義如下:

template < class Key, class T, class Pred = less<Key>, class A = allocator<T> >
class map{
    ...
    typedef pair< const Key, T > value_type;
    ...
};

map 和 multimap 十分類似,區別在於 map 容器中元素的關鍵字不能重複。multimap 有的成員函數,map 都有。此外,map 還有成員函數 operator[]:

T & operator[] (Key k);

該成員函數返回 first 值為 k 的元素的 second 部分的參照。如果容器中沒有元素的 first 值等於 k,則自動新增一個 first 值為 k 的元素。如果該元素的 second 成員變數是一個物件,則用無參建構函式對其初始化。

下面的程式演示了 map 的用法。
#include <iostream>
#include <map>  //使用map需要包含此標頭檔案
using namespace std;
template <class T1,class T2>
ostream & operator <<(ostream & o,const pair<T1,T2> & p)
{ //將pair物件輸出為 (first,second)形式
    o << "(" << p.first  << "," << p.second << ")";
    return o;
}
template<class T>
void Print(T first,T last)
{//列印區間[first,last)
    for( ; first != last; ++ first)
        cout <<  * first << " ";
    cout << endl;
}
typedef map<int,double,greater<int> > MYMAP; //此容器關鍵字是整型,元素按關鍵字從大到小排序
int main()
{
    MYMAP mp;
    mp.insert(MYMAP::value_type(15,2.7));
    pair<MYMAP::iterator,bool> p = mp.insert(make_pair(15,99.3));
    if(!p.second)
        cout << * (p.first) << " already exists" << endl; //會輸出
    cout << "1) " << mp.count(15) << endl; //輸出 1) 1
    mp.insert(make_pair(20,9.3));
    cout << "2) " << mp[40] << endl;//如果沒有關鍵字為40的元素,則插入一個
    cout << "3) ";Print(mp.begin(),mp.end());//輸出:3) (40,0)(20,9.3)(15,2.7)
    mp[15] = 6.28; //把關鍵字為15的元素值改成6.28
    mp[17] = 3.14; //插入關鍵字為17的元素,並將其值設為3.14
    cout << "4) ";Print(mp.begin(),mp.end());
    return 0;
}
程式的輸出結果如下:
(15,2.7) already exists
1) 1
2) 0
3) (40,0) (20,9.3) (15,2.7)
4) (40,0) (20,9.3) (17,3.14) (15,6.28)

第 17 行的greater <int> >最右邊的兩個>之間要有空格,否則 Dev C++ 會將它們當作右移運算子,導致編譯出錯。在 Visual Studio 2010 中無此問題。

第 22 行用 STL 中的函數模板 make_pair 生成一個 pair 模板類物件插入 mp 中。

第 23 行,如果插入成功,p.second 的值會是 true。顯然這裡不能成功,因為 map 不允許關鍵字重複。因為關鍵字重復而插入失敗時,p.first 就指向容器中關鍵字相同的那個元素。

第 27 行要存取關鍵字為 40 的元素。在沒有這個元素的情況下,一個關鍵字為 40、值為 0 的元素被自動插入容器。mp[40] 等價於mp.operator[](40);,其返回值是關鍵字為 40 的那個元素(不論是原有的還是新插入的)的 second 成員變數的參照。第 29 行和第 30 行的道理與此類似。