順序容器是按照它們在容器中的位置來順序保存和訪問的,而關聯容器是按照關鍵字來保存和訪問的。
1、初始化
關聯容器分爲兩類:map和set.
a)、map是關鍵字-值對;set只有關鍵字。
map定義:
map<string,size_t> word_count = { {“Jon”,0},
{"Lucy",1},
{"Dicken",2} };
該定義將string映射到size_t,也就是說string是下標,size_t是值。
如:word_count[word];//返回下標爲word的map容器的size_t的值。
b)、set定義:
map<string,size_t> word_count = { {“Jon”,0},
{"Lucy",1},
{"Dicken",2} };
新標準中可以列表初始化。
multimap和multiset:
關鍵字不唯一,即多個元素可以具有相同的關鍵字。
2、關鍵字類型
不是所有類型都可以用作關聯容器的關鍵字。對於有序容器——map、multimap、set、multiset,關鍵字類型必須定義元素比較的方法(默認使用“<”關鍵字)。
使用自己定義的操作,在定義關聯容器時需要提供比較操作類型。
如:
multiset<Sales_data, decltype(compareIsbn)*>
bookstore(compareIsbn);
其中decltype(compareIsbn)*定義了一個指向compareIsbn函數的指針類型,該函數定義了Sales_data中的元素比較的方法。函數定義如下:
bool compareIsbn(const Sales_data &lhs, const Sales_data &rhs)
{
return lhs.isbn() < rhs.isbn();
}
該函數對Sales_data中的成員函數.isbn()進行比較,返回一個布爾量表示兩者的大小。
3、pair對象
map的成員是pair類對象。
pair與容器類似,是用來生成特定類型的模板。一個pair保存兩個數據成員,它們類型可以不同。
如:
pair<string, size_t> word_count;//該pair保存一個string 和一個size_t
pair可以列表初始化,如:
pair<string, string> author{"James", "Joyce"};
定義了一個包含兩個string的pair類對象author。
pair數據成員的獲取:
pair.first;//返回pair第一個(公有)數據成員
pair.second;//返回pair第二個(公有)數據成員
4、關聯容器操作
a)、對關聯容器迭代器解引用,得到一個類型爲容器的value_type的值的引用。
對map而言,value_type是一個pair類型,其first成員保存const的關鍵字,second成員保存值。
b)、和順序容器一下,我們也可以通過迭代器遍歷關聯容器。
c)、增加元素:
c.insert(arge);
arge可以是對象(將此對象插入容器中)、迭代器範圍(將迭代器範圍內的所有元素插入容器)、迭代器和對象(將對象插入迭代器所指定的範圍)。
d)、刪除元素:
c.erase(arge);
arge可以爲關鍵字(刪除該關鍵字對應的所有對象)、迭代器(刪除該迭代器指向的對象)、迭代器範圍(刪除迭代器範圍所有元素)。
e)、下標操作:
set類型不支持下標操作。
map類型下標運算返回與下標關鍵字關聯的值。注意,如果關鍵字不在map中,則會自動創建一個元素並插入到map中。
特別注意,對一個map進行下標操作時,會獲得一個mapped_type對象(map類的值);但當解引用一個map迭代器時,得到一個value_type對象(pair)。
f)、訪問元素
c.find(k);//返回第一個指向關鍵字k的迭代器
對map的下標操作可能會改變map(當下標關鍵字不在map中時),因此對於不想改變原有map內容的訪問元素操作,我們應該使用find代替來下標操作。
c.count(k);//返回關鍵字等於k的元素數量
c.lower_bound(k);//返回一個迭代器,指向第一個關鍵字不小於k 的元素
c.upper_bound(k);//返回一個迭代器,指向第一個關鍵字大於k的元素
結合使用c.lower_bound(k)和c.upper_bound(k)可以獲得一個迭代器範圍,表示所有具有關鍵字k的元素範圍。
c.equal_range(k);//返回一個pair,保存一對迭代器,分別指向第一個關鍵字不小於k 的元素和第一個關鍵字大於k的元素
5、無序容器
無序容器不使用比較運算符來組織元素,而是使用一個哈希函數和關鍵字類型的==運算符。