題記:本系列學習筆記(c++ primer學習筆記)主要目的是討論一些容易被大家忽略或者容易形成錯誤認識的內容。只適合於有了一定的c++基礎的讀者(至少學完一本c++教程)。
本文主要討論c++標準庫中的關聯容器(associative container),內容主要涉及map, set, multimap和multiset四類容器。
如果文中有錯誤或遺漏之處,敬請指出,謝謝! 概述
關聯容器(associative container)與順序容器(sequential container)的本質區別在於:關聯容器是通過鍵(key)儲存和讀取元素的,而順序容器則通過元素在容器中的位置順序儲存和訪問元素。
關聯容器支援通過鍵來高效地查詢和讀取元素,兩個基本的關聯容器是map和set。map的元素是「鍵-值」對的二元組形式:鍵用作元素在map中的索引,而值則表示所儲存和讀取的資料。set僅包含乙個鍵,並有效地支援關於某個鍵是否存在的查詢。set和map型別的物件所包含的元素都具有不同的鍵。如果需要乙個鍵對應多個例項,則需要使用multimap或multiset型別。這兩種型別允許多個元素擁有相同的鍵。
map關聯陣列:元素通過鍵來儲存和讀取
set大小可變的集合,支援通過鍵實現的快速讀取
multimap
支援同乙個鍵多次出現的map型別
multiset
支援同乙個鍵多次出現的set型別
pair型別
pair模板類用來繫結兩個物件為乙個新的物件,該型別在標頭檔案中定義。pair型別提供的操作如下表:
pairp1;
建立乙個空的pair物件,它的兩個元素分別是t1和t2型別,採用值初始化
pairp1(v1, v2);
建立乙個pair物件,它的兩個元素分別是t1和t2型別,其中first成員初始化為v1,second成員初始化為v2
make_pair(v1, v2)
以v1和v2值建立乙個新的pair物件,其元素型別分別是v1和v2的型別
p1 < p2
字典次序:如果p1.firstp1 == p2
如果兩個pair物件的first和second成員依次相等,則這兩個物件相等。
p.first
返回p中名為first的(公有)資料成員
p.second
返回p中名為second的(公有)資料成員
關聯容器
關聯容器共享大部分順序容器的操作,但不提供front, push_front, back, push_back以及pop_back操作。
具體而言,有順序容器中的:前三種建構函式;關係運算;begin, end, rbegin和rend操作;型別別名;swap和賦值操作,但關聯容器不提供assign函式;clear和erase函式,但erase函式返回void型別;關於容器大小的操作,但resize函式不能用於關聯容器。
map型別
map::key_type
在map容器內,用做索引的鍵的型別
在map容器中,鍵所關聯的值的型別
map::value_type
注意:map的元素型別為pair型別,且鍵成員不可修改。其它型別別名與順序容器一樣。
map物件的定義
mapm;
建立乙個名為m的空map物件,其鍵和值的型別分別為k和v
mapm(m2);
建立m2的副本m,m與m2必須有相同的鍵型別和值型別
mapm(b, e);
建立map型別的物件m,儲存迭代器b和e標記的範圍內所有元素的副本。元素的型別必須能轉換為pair
鍵型別的約束
在使用關聯容器時,它的鍵不但有乙個型別,而且還有乙個相關的比較函式。預設情況下,標準庫使用鍵型別定義的 < 操作符來實現鍵的比較。這個比較函式必須滿足:當乙個鍵和自身比較時,結果必定是false;當兩個鍵之間都不存在「小於」關係時,則容器將之視為相同的鍵。也就是說,map內的元素按鍵值公升序排列。
operator
a::reference operator(const key& key);
操作符返回鍵key所關聯的值的引用;如果該鍵key不存在,則向map物件新增乙個新的元素,元素的鍵為key,所關聯的值採用值初始化。(要特別留意這個***)
例如:map wordcount; // empty map
word_count["hello"] = 1;
上面的**首先建立乙個空的map物件,然後執行下列步驟:
1)在wordcount中查詢鍵為「hello」的元素,沒有找到;
2)將乙個新的鍵-值對插入到wordcount中,其中,鍵為「hello」,值為0
3)讀取新插入的鍵-值對的值,並將它的值賦為1。
#
include
<
iostream
>
#include
<
map>
using
namespace
std;
int main(
)
map::insert
m.insert(e)
e是乙個用在m上的value_type型別的值,如果鍵(e.first)不在m中,則插入e到m中;如果鍵已經在m中存在,則保持m不變。
該函式返回乙個pair型別物件,如果發生了插入動作,則返回pair(it, true);否則返回pair(it, false)。其中,it是指向鍵為e.first那個元素的迭代器。
m.insert(beg, end)
beg和end是標記元素範圍的迭代器,其中的元素必須為value_type型別的鍵-值對。對於該範圍內的所有元素,如果它的鍵在m中不存在,則將該鍵及其關聯的值插入到m。返回void型別。
m.insert(iter, e)
insert(e),並以iter為起點搜尋新元素的位置。返回乙個迭代器,指向m中鍵為e.first的元素。
注:當需要插入乙個map元素時,一是可以用map::value_type來構造乙個pair物件,另外,也可以用make_pair來構造這個物件。
查詢元素
m.count(k)
返回m中k的出現次數(0或1)
m.find(k)
如果容器中存在鍵為k的元素,則返回指向該元素的迭代器。
如果不存在,則返回end()值。
刪除元素
m.erase(k)
刪除m中鍵為k的元素,返回size_type型別的值,表示刪除的元素個數(0或1)
m.erase(p)
從m中刪除迭代器p所指向的元素。p必須指向m中確實存在的元素,而且不能等於e.end()。返回void型別
m.erase(b, e)
從m中刪除[b, e)範圍內的元素,返回void型別
set型別
multimap和multiset型別
map和set容器中,乙個鍵只能對應乙個例項。而multiset和multimap型別則允許乙個鍵對應多個例項。
multimap和multiset所支援的操作分別與map和set的操作相同,只有乙個例外:multimap不支援下標運算。為了順序乙個鍵可以對應多個值這一特性,map和mulitmap,或set和multiset中相同的操作都以不同的方式做出了一定的修改。
元素的新增和刪除
map和set容器中的insert和erase操作同樣適用於multimap和multiset容器,實現元素的新增和刪除。
由於鍵不要求是唯一的,因此每次呼叫insert總會新增乙個元素。
而帶有乙個鍵引數的erase將刪除擁有該鍵的所有元素,並返回刪除元素的個數;而帶有乙個或一對迭代器引數的erase版本只刪除指定的元素,並返回void型別。
查詢元素
在map和set容器中,元素是有序儲存的(公升序),同樣multimap和multiset也一樣。因此,在multimap和multiset容器中,如果某個鍵對應多個例項,則這些例項在容器中將相鄰存放,即迭代遍歷時,可保證依次返回特定鍵所關聯的所有元素。
1)配合使用find和count來查詢:count函式求出某鍵出現的次數,而find操作返回指向第乙個鍵的例項的迭代器。
2)使用lower_bound和upper_bound函式:這兩個函式常用於multimap和multiset,但也可以用於map和set容器。所有這些操作都需要傳遞乙個鍵,並返回乙個迭代器。
m.lower_bound(k)
返回乙個迭代器,指向鍵不小於k的第乙個元素
m.upper_bound(k)
返回乙個迭代器,指向鍵大於k的第乙個元素
m.equal_range(k)
返回乙個迭代器的pair物件;它的first成員等價於
m.lower_bound(k),而second成員則等價於
m.upper_bound(k)
注意:形成的有效區間是[lower_bound(k), upper_bound(i)),是個半開半閉區間。
lower_bound返回的迭代器不一定指向擁有特定鍵的元素。如果該鍵不在容器中,則lower_bound返回在保持容器元素順序的前提下該鍵應被插入的第乙個位置。
若鍵不存在,返回的迭代器相同。
3)使用equal_range,其實質跟法2)相同。
如果文中有錯誤或遺漏之處,敬請指出,謝謝!
[1] c++ primer(edition 4)
[2] thinking in c++(volume two, edition 2)
[3] international standard:iso/iec 14882:1998
《C Primer》學習筆記 關聯容器
一,pair型別 pairp1 建立乙個空pair指標,兩個元素分別是t1,t2型別,採用值初始化 pairp1 v1,v2 first成員初始化為v1,second成員為v2 make pair v1,v2 建立新的pair物件 p1 p2 p1 p2 p.first 返回first成員 p.se...
c primer 學習筆記18 關聯容器
關聯容器和順序容器的本質差別在於 關聯容器通過鍵 key 儲存和讀取元素,而順序容器則通過元素在容器中的位置順序儲存和訪問元素。關聯容器 associative containers 支援通過鍵來高效地查詢和讀取元素。兩個基本的關聯容器型別是 map 和set。map 的元素以鍵 值 key val...
C Primer 學習筆記 關聯容器初識
關聯容器中元素按照關鍵字來訪問和儲存 map key value對 字典中單詞是key,單詞釋義是value 關聯陣列,set 只儲存關鍵字 multimap multiset 允許多個元素具有相同的關鍵字 map map map words string word while cin word f...