和順序容器不同,關聯容器是通過鍵值對的方式儲存資料的,可以通過鍵來讀取資料。c++中主要的關聯容器是map和set兩種,它們都只能為乙個鍵新增乙個值,如果希望新增多個值,應該使用multimap和multiset。在了解簽名提到的幾個關聯容器之前,我們需要先了解c++另乙個簡單的關聯容器,它是所有關聯容器中最簡單的表達方式。
pair型別是c++標準庫提供的乙個簡單的關聯容器,它包含在utility標頭檔案中,它的主要方法如下:
考慮下面三條語句:
pairpair1;
pairpair2("one",1);
pair= make_pair("two",2);
上面的三個方法都可以用於建立乙個pair物件,pair1和pair2的區別在於,pair1用的是預設值進行初始化,pair2是指定了值得物件的。同時,也可以通過呼叫make_pair方法建立乙個pair物件。
因為pair的宣告比較長,如果需要多次用到,可以使用別名:
typedef pairbook;
book book1;
book book2;
pair提供了兩個公開的成員物件,first和second,通過成員操作符就可以使用他們。如下:
cout<
map型別是鍵值對的集合,也是一種關聯容器,也可以說它是pair型別的集合。訪問它的元素的時候,是通過鍵來獲取資料的而不是根據儲存的位置讀取的。下面了解它的特徵:
和大部分容器一樣,map也提供基本的建構函式,如下:
使用如下:
mapmap1;
mapmap2(map1);
mapmap3(map1.begin(),map1.end());
在這裡最主要的是提醒大家,可以作為key的資料型別,必須是可以進行比較的,這樣map容器才能判斷key是否是相同的從而達到乙個容器只有唯一key的目的。即作為key的資料型別必須支援《比較操作符。
注意的一點是,鍵的值是不可以修改的。
mapmap1;
map::iterator iter=map1.begin();//等同於引用了map的首個資料型別為pair物件。
//可以通過first,second成員訪問鍵和值
cout
coutsecond+1;
map容器可通過使用下標的方式獲取值,和順序容器不同,它的下標是鍵。考慮如下**:
mapmap1;
map1["one"]=1;
上述**會發生如下步驟:
①、判斷map1是否存在one的鍵,得出不存在。
②、新建乙個pair物件。
③、將新建的物件插入map1中。
④、修改map1中one對應的值為1。
在看下面的一段**:
string key;
while(cin>>key)
map提供了insert操作用於新增元素,它的好處在於,相對於下標,它不用通過值初始化,而是直接賦值。insert主要有三個版本:如下:
考慮一下**:
mapmap1;
map1.insert(mapvalue_type("one",1));
//因為map::value_type等同於pairmap1.insert(make_pair("two",2);
//也可以使用別名簡略寫法
typedef map::value_type maptype;
map1.insert(maptype("threee",3));
此insert版本的實參是乙個value_type型別,會返回乙個包含當前插入元素的迭代器以及乙個bool值得valuetype型別。
pair::iterator,bool> pair1=map1.insert(make_pair("one",1));
//通過bool判斷是否插入成功
if(!(pair1->second)//表示已經存在該元素
上述操縱向map1插入乙個鍵值對,如果map1存在key對應的鍵,則插入失敗,否則就插入成功。可通過bool進行判斷。iterator是乙個指向插入的鍵的元素的迭代器物件。可通過它來訪問該值。
用下標查詢元素的時候,如果該key的元素不存在,會往map插入元素。但是有時候我們只是想查詢元素,不存在的時候並不需要新增。這個時候怎麼辦呢?標準庫提供了如下兩個方法:
使用如下:
mapmap1;
if(map1.count("one")==1)
cout<::iterator iter='map1.find("one");
if(iter!=map1.end())
cout
count方法會返回key出現的次數。在map中,改返回結果只能是0或者1。find()方法返回的是乙個迭代器物件,可以直接讀取元素值。如果指定的key不存在,返回map容器最後乙個元素的下一元素的迭代器,否則返回key指向的元素的迭代器。
set嚴格意義上來說,它不能算乙個關聯容器,但是它卻經常和關聯容器一起工作。它的主要作用是儲存key。在set中,每個key都是唯一的。
考慮一下**:
vectorvect;
for(vector::size_type i=0;i<9;i++)
setset1(vect.begin(),vect.end());
cout會發現,vect存在20個元素而set只有10個元素。原因在於set遇到相同的值只儲存乙個。
同樣的,大部門map支援的操作,set也支援。比如count,find......
由於map和set中每個鍵只能對應乙個值,因此就出現了multimap和multiset,它們的每個鍵都可以對應多個例項。由於乙個鍵對應多個例項,因此,不能使用下標反問他們的元素,除此之外,其他操作和mapset沒有任何不同。
由於multi版本的map.set可以重複新增例項,所以新增操作總是成功的。
multimapmap1;
map1.insert(make_pair("one",1));
map1.insert(make_pair("one",2));
上述操作是可以成功的。
雖然不可以用下標讀取元素,但是可以使用find和count結合讀取元素。
typedef map::size_type maptype;
maptype sum=map1.count("one");
map::iterator iter=map1.begin();
for(maptype i=0;isecond<
刪除元素可以呼叫erase方法。
map1.erase("one")
map::iterator iter=map1.begin();
map1.arase(iter);
如果是直接傳遞鍵的方式,將會刪除所有的元素,並返回被刪除的個數。如果是迭代器版本的,只刪除指定的物件。
上述關聯容器就這麼多了,還有很多其他的操作都是和順序容器一樣的,讀者需要多實踐。
---------文章寫自:hyharden---------
'>
關聯容器set map的使用
關聯容器是stl容器的另一組成部分,關聯容器的底層是紅黑樹,容器會根據值進行自動調整排序。map與set的底層資料結構決定了他們不會有重複的元素,set.count 函式返回的結果只能整數 0 或 1,1表示有這個元素,0表示沒有這個元素 與其功能相似的還有函式find find 函式返回值是乙個迭...
11 1使用關聯容器
map是stl的乙個容器,和set一樣,map也是一種關聯式容器。它提供一對一 其中第乙個可以稱為關鍵字,每個關鍵字只能在map中出現一次,第二個可能稱為該關鍵字的值 的資料處理能力,由於這個特性,有助於我們處理一對一資料。map內部是自建一顆紅黑樹 一種非嚴格意義上的平衡二叉樹 這顆樹具有對資料自...
C 關聯容器的使用例項
include include include include include include include using namespace std class textquery void read file ifstream is string text line line no const ...