11.3 關(guān)聯(lián)容器操作

??關(guān)聯(lián)容器有三個(gè)額外的類型別名:key_type盒刚、mapped_type郁季、value_type美侦。

set<string>::value_type v1;  //v1是一個(gè)string
set<string>::key_type v2;  //v1是一個(gè)string
map<string, int>::value_type v3;  //v3是一個(gè)pair<const string,int>
map<string, int>::key_value v4;  //v4是一個(gè)string
map<string, int>::mapped_type v5;  //v5是一個(gè)int

關(guān)聯(lián)容器迭代器

??當(dāng)解引用一個(gè)關(guān)聯(lián)容器迭代器時(shí)镜会,我們會(huì)得到一個(gè)類型為容器value_type的值的引用虑稼。對(duì)map而言琳钉,value_type是一個(gè)pair類型,其first成員保存const的關(guān)鍵字蛛倦,second成員保存值:

//獲得指向word_count中一個(gè)元素的迭代器
auto map_it = word_count.begin();
//*map_it是指向一個(gè)pair<const string,size_t>對(duì)象的引用
cout << map_it->first;  //打印此元素的關(guān)鍵字
cout << " " << map_it->second;  //打印此元素的值
map_it->first = "new key";  //錯(cuò)誤:關(guān)鍵字是const的
++map_it->second;  //正確:我們可以通過迭代器改變?cè)?

??set的迭代器是const的
??雖然set類型同時(shí)定義了iterator和const_iterator類型歌懒,但兩種類型都只允許只讀訪問set中的元素。

??遍歷關(guān)聯(lián)容器
??map和set都支持begin和end操作溯壶。我們可以用它們來進(jìn)行遍歷容器及皂。

//獲得一個(gè)指向首元素的迭代器
auto map_it = word_count.cbegin();
//比較當(dāng)前迭代器和尾后迭代器
while (map_it != word_count.cend()) {
    //解引用迭代器甫男,打印關(guān)鍵字-值對(duì)
    cout << map_it->first << " occurs"
        << map_it->second << " times" << endl;
    ++map_it;  //遞增迭代器,移動(dòng)到下一個(gè)元素
}

??關(guān)聯(lián)容器和算法
??我們通常不對(duì)關(guān)聯(lián)容器使用泛型算法验烧,關(guān)鍵字是const這一特性意味著不能將關(guān)聯(lián)容器傳遞給修改或重排容器元素的算法板驳。在實(shí)際編程中,如果我們真要對(duì)一個(gè)關(guān)聯(lián)容器使用算法碍拆,要么是將它作一個(gè)源序列若治,要么當(dāng)作一個(gè)目的位置。

添加元素

??關(guān)聯(lián)容器的insert成員向容器中添加一個(gè)元素或一個(gè)元素范圍倔监。由于map和set包含不重復(fù)的關(guān)鍵字直砂,因此插入一個(gè)已存在的元素對(duì)容器沒有任何影響:

vector<int> ivec = { 2,4,6,8,2,4,6,8 };  //ivec有8個(gè)元素
set<int> set2;  //空集合
set2.insert(ivec.cbegin(), ivec.cend());  //set2有4個(gè)元素
set2.insert({ 1,3,5,7,1,3,5,7 });  //set2現(xiàn)在有8個(gè)元素

??insert有兩個(gè)版本,分別接受一對(duì)迭代器浩习,或是一個(gè)初始化器列表静暂。

??向map添加元素
??對(duì)一個(gè)map進(jìn)行insert操作時(shí),必須記住元素類型是pair谱秽。

//向word_count插入word的4種方法
word_count.insert({ word,1 });
word_count.insert(make_pair(word, 1));
word_count.insert(pair<string, size_t>(word, 1));
word_count.insert(map<string, size_t>::value_type(word, 1));

??檢測(cè)insert的返回值
??insert的返回值依賴于容器類型和參數(shù)洽蛀。對(duì)于不包含重復(fù)關(guān)鍵字的容器,添加單一元素的insert和emplace版本返回一個(gè)pair疟赊,pair的first成員是一個(gè)迭代器郊供,指向具有給定關(guān)鍵字的元素;second成員是一個(gè)bool值近哟,指出元素是插入成功還是已經(jīng)存在于容器中驮审。

??向multiset和multimap添加元素
??由于multi容器中的關(guān)鍵字不必唯一,在這些類型上調(diào)用insert總會(huì)插入一個(gè)元素:

multimap<string, string> authors;
//插入第一個(gè)元素吉执。關(guān)鍵字為Barth,John
authors.insert({ "Barth,John","Sot-Weed Factor" });
//正確:添加第二個(gè)元素疯淫,關(guān)鍵字也是Barth,John
authors.insert({ "Barth,John","Lost in the Funhouse" });

刪除元素

??關(guān)聯(lián)容器定義了三個(gè)版本的erase戳玫,與順序容器一樣熙掺,我們可以通過傳遞給erase一個(gè)迭代器或一對(duì)迭代器來刪除一個(gè)元素或者一個(gè)元素范圍。關(guān)聯(lián)容器還提供一個(gè)額外的erase操作咕宿,它接受一個(gè)key_type參數(shù)币绩。此版本刪除所有匹配給定關(guān)鍵字的元素,返回實(shí)際刪除的元素的數(shù)量:

//刪除一個(gè)關(guān)鍵字府阀,返回刪除的元素?cái)?shù)量
if (word_count.erase(removal_word))
cout << "ok: " << removal_word << " removed\n";
else cout << "oops: " << removal_word << " not found!\n";

map的下標(biāo)操作

??map和unordered_map容器提供了下標(biāo)運(yùn)算符和一個(gè)對(duì)應(yīng)的at函數(shù)缆镣。set類型不支持下標(biāo)。

map<string, size_t> word_count;  //empty map
//插入一個(gè)關(guān)鍵字為Anna的元素试浙,關(guān)聯(lián)值進(jìn)行值初始化费就,然后將1賦予它
word_count["Anna"] = 1;

??使用下標(biāo)運(yùn)算符可能插入一個(gè)新元素,我們只可以對(duì)非const的map使用下標(biāo)操作川队。

??使用下標(biāo)操作的返回值
??map的下標(biāo)元素符與我們用過的其他下標(biāo)運(yùn)算符的另一個(gè)不同之處是其返回類型力细。當(dāng)對(duì)一個(gè)map進(jìn)行下標(biāo)操作時(shí),會(huì)獲得一個(gè)mapped_type對(duì)象固额;但當(dāng)解引用一個(gè)map迭代器時(shí)眠蚂,會(huì)得到一個(gè)value_type對(duì)象。如果關(guān)鍵字還未在map中斗躏,下標(biāo)運(yùn)算符會(huì)添加一個(gè)新元素逝慧。

訪問元素

??關(guān)聯(lián)容器提供多種查找一個(gè)指定元素的方法,例如find和count啄糙。

set<int> iset = { 0,1,2,3,4,5,6,7,8,9 };
iset.find(1);  //返回一個(gè)迭代器笛臣。指向key==1的元素
iset.find(11);  //返回一個(gè)迭代器,其值等于iset.end()
iset.count(1);  //返回1
iset.count(11);  //返回0

??在multimap和multiset中查找元素
??在容器中可能有很多元素具有給定的關(guān)鍵字隧饼,如果一個(gè)multimap和multiset中有多個(gè)元素具有給定關(guān)鍵字沈堡,則這些元素在容器中會(huì)相鄰存儲(chǔ)。燕雁。

string search_item("Alain de Botton");  //要查找的作者
auto entries = authors.count(search_item);  //元素的數(shù)量
auto iter = authors.find(search_item);  //此作者的第一本書
//用一個(gè)循環(huán)查找此作者的所有著作
while (entries) {
    cout << iter->second << endl;  //打印每個(gè)題目
    ++iter;   //前進(jìn)到下一本書
    --entries;  //記錄已經(jīng)打印了 多少本書
}

??一種不同的诞丽,面向迭代器的解決方法
??我們還可以用lower_bound和upper_bound來解決此問題。這兩個(gè)操作接受一個(gè)關(guān)鍵字拐格,返回一個(gè)迭代器僧免。如果關(guān)鍵字在容器中,lower_bound返回迭代器將指向第一個(gè)具有給定關(guān)鍵字的元素捏浊,而upper_bound返回的迭代器則指向最后一個(gè)匹配給定關(guān)鍵字的元素之后的位置懂衩。如果不在multimap中,則lower_bound和upper_bound會(huì)返回相等的迭代器金踪,指向一個(gè)不影響排序的關(guān)鍵字插入位置浊洞。

 //authors和search_item的定義。與前面的程序一樣
//beg和end表示對(duì)應(yīng)此作者的元素的范圍
for (auto beg = authors.lower_bound(search_item),
    end = authors.upper_bround(search_item);
    beg != end; ++beg)
    cout << beg->second << endl;  //打印每個(gè)題目

??equa_range函數(shù)
??解決此問題的最后一種方法是三種方法中最直接的:直接調(diào)用equal_range即可热康。此函數(shù)接受一個(gè)關(guān)鍵字沛申,返回一個(gè)迭代器pair。若關(guān)鍵字存在姐军,則第一個(gè)迭代器指向第一個(gè)與關(guān)鍵字匹配的元素铁材,第二個(gè)迭代器指向最后一個(gè)匹配元素的位置,若未找到元素奕锌,則兩個(gè)迭代器都指向關(guān)鍵字可以插入的位置著觉。

//authors和search_item的定義。與前面的程序一樣
//pos保存迭代器對(duì)惊暴,v表示與關(guān)鍵字匹配的元素范圍
for (auto pos = authors.equal_range(search_item);
    pos.first != pos.second; ++pos.first)
    cout << pos.first->second << endl;  //打印每個(gè)題目
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末饼丘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子辽话,更是在濱河造成了極大的恐慌肄鸽,老刑警劉巖卫病,帶你破解...
    沈念sama閱讀 216,470評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異典徘,居然都是意外死亡蟀苛,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門逮诲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來帜平,“玉大人,你說我怎么就攤上這事梅鹦●伤Γ” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵齐唆,是天一觀的道長嗤栓。 經(jīng)常有香客問我,道長蝶念,這世上最難降的妖魔是什么抛腕? 我笑而不...
    開封第一講書人閱讀 58,176評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮媒殉,結(jié)果婚禮上担敌,老公的妹妹穿的比我還像新娘。我一直安慰自己廷蓉,他們只是感情好全封,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著桃犬,像睡著了一般刹悴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上攒暇,一...
    開封第一講書人閱讀 51,155評(píng)論 1 299
  • 那天土匀,我揣著相機(jī)與錄音,去河邊找鬼形用。 笑死就轧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的田度。 我是一名探鬼主播妒御,決...
    沈念sama閱讀 40,041評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼镇饺!你這毒婦竟也來了乎莉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,903評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎惋啃,沒想到半個(gè)月后哼鬓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肥橙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評(píng)論 2 332
  • 正文 我和宋清朗相戀三年魄宏,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片存筏。...
    茶點(diǎn)故事閱讀 39,703評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖味榛,靈堂內(nèi)的尸體忽然破棺而出椭坚,到底是詐尸還是另有隱情,我是刑警寧澤搏色,帶...
    沈念sama閱讀 35,417評(píng)論 5 343
  • 正文 年R本政府宣布善茎,位于F島的核電站,受9級(jí)特大地震影響频轿,放射性物質(zhì)發(fā)生泄漏垂涯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評(píng)論 3 325
  • 文/蒙蒙 一航邢、第九天 我趴在偏房一處隱蔽的房頂上張望耕赘。 院中可真熱鬧,春花似錦膳殷、人聲如沸操骡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽册招。三九已至,卻和暖如春勒极,著一層夾襖步出監(jiān)牢的瞬間是掰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評(píng)論 1 269
  • 我被黑心中介騙來泰國打工辱匿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留键痛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,711評(píng)論 2 368
  • 正文 我出身青樓掀鹅,卻偏偏與公主長得像散休,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子乐尊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 1. 使用關(guān)聯(lián)容器 2. 關(guān)聯(lián)容器概述2.1 定義關(guān)聯(lián)容器2.2 關(guān)鍵字類型的要求2.3 pair類型 3. 關(guān)聯(lián)...
    MrDecoder閱讀 477評(píng)論 0 0
  • 關(guān)聯(lián)容器和順序容器根本的不同: 關(guān)聯(lián)容器中的元素是按關(guān)鍵字保存和訪問的戚丸;順序容器中的元素是按在容器中的位置順序保存...
    Kreat閱讀 193評(píng)論 0 0
  • 第11章 關(guān)聯(lián)容器 關(guān)聯(lián)容器類型描述map保存關(guān)鍵字-值對(duì)multimap關(guān)鍵字可重復(fù)的mapset保存關(guān)鍵字mu...
    北冥有魚wyh閱讀 371評(píng)論 0 1
  • 簡介 標(biāo)準(zhǔn)庫提供8個(gè)關(guān)聯(lián)容器: map:關(guān)聯(lián)數(shù)組 set:只保存關(guān)鍵字 multimap:關(guān)鍵字可重復(fù)出現(xiàn)的map...
    TOMOCAT閱讀 244評(píng)論 0 0
  • 關(guān)聯(lián)容器 關(guān)聯(lián)容器支持高效的關(guān)鍵字查找和訪問,兩個(gè)主要的關(guān)聯(lián)容器是map和set,map中的元素是一些關(guān)鍵字-值(...
    土豆吞噬者閱讀 369評(píng)論 0 0