標籤:

《C++ Primer》讀書筆記-第十一章 03 關聯容器操作

春節的原因,這一節拖延了好久,感謝春晚,讓我有時間更新~

祝大家雞年大吉,在家的時候多陪陪家人。

聲明:

  • 文中內容收集整理自《C++ Primer 中文版 (第5版)》,版權歸原書所有。
  • 原書有更加詳細、精彩的釋義,請大家購買正版書籍進行學習。
  • 本文僅作學習交流使用,禁止任何形式的轉載

正文

關聯容器額外的類型別名

  • key_type 關鍵字類型
  • mapped_type map值類型
  • value_type

只有map類型才定義了mapped_type

map<string, int>::value_type v3;n

v3是一個pair<const string, int>

由於我們不能改變一個元素的關鍵字,因此pair的關鍵字部分是const的

關聯容器迭代器

auo map_it = word_count.begin(); ncout << map_it->first;n

解引用關聯容器的迭代器,會得到一個類型為容器的value_type的值的引用。

set的迭代器是const的

遍歷關聯容器

auto map_it = word_count.cbegin(); nwhile( map_it != word_count.cend() ) n{ n cout << map_it->first << " occurs " << map_it->second << " times " << endl; n ++map_it; n} n

通常不對關聯容器使用泛型演算法

  1. 關鍵字是const的,很多修改或重排容器元素的演算法不適用
  2. 對於只讀演算法,很多都要搜索序列,使用關聯容器專用的find成員會比調用泛型find快是多

添加元素

vector<int> ivec = { 2, 4, 2, 4 }; nset<int> set2; nset2.insert( ivec.begin(), ivec.end() ); nset2.insert( { 1, 3, 1, 3 } ); n

insert向容器添加一個元素或一個元素範圍,添加已經存在的元素對容器沒有任何影響

向map添加元素

map中需要添加pair類型的元素

word_count.insert({word, 1}); nword_count.insert(make_pair(word,1)); nword_count.insert(pair<string,size_t>(word,1)); nword_count.insert(map<string,size_t>::value_type(word,1)); n

insert返回值

對於不包含重複關鍵字的容器,insert返回一個pair。它的first成員是一個迭代器,指向具有給定關鍵字的元素,second成員是一個bool值,如果關鍵字已經在容器中,返回一個false

用insert重寫單詞計數程序

map<string, size_t> word_count; nstring word; nwhile(cin >> word) n{ n auto ret = word_count.insert({word, 1}); n if(!ret.second) n { n ++ret.first->second; n } n} n

具體的解釋參考P385

向multiset或multimap添加元素

multimap<string, string> authors; nauthors.insert({"author1", "book1"}); nauthors.insert({"author1", "book2"}); n

對允許重複關鍵字的容器,insert返回一個指向新元素的迭代器。無須返回一個bool值,因為總是會插入新元素

刪除元素

接受三種類型的參數

  • 一個迭代器
  • 一個迭代器範圍
  • 關鍵字類型的值

返回實際刪除的元素的數量(允許重複關鍵字的容器,刪除元素的數量可能大於1)

map的下標操作

僅map和unordered_map提供了下標操作

與其他下標運算符不同的是:

如果關鍵字不在map中,會創建一個元素插入到map中,關聯值將進行值初始化

c[k] 若關鍵字不在容器中會添加 nc.at(k) 若關鍵字不在容器中會拋異常 n

map的下標操作返回的是一個mapped_type對象

訪問元素

下標和at操作只適用於非const的map和unordered_map,且下標在元素不存在時會執行插入操作,有時這並不是我們想要的。

關聯容器提供了其他查找指定元素的方法

  • c.find(k)
  • c.count(k)
  • c.lower_bound(k)
  • c.upper_bound(k)
  • c.equal_range(k)

find返回一個迭代器,指向第一個關鍵字為k的元素,若k不存在,則返回尾後迭代器

lower_bound和upper_bound不適用於無序容器

在multimap和multiset中查找元素

如果多個元素有相同的關鍵字,則它們在容器中是相鄰存儲的。

如果想把具有同一關鍵字的所有元素都列印出來,最直觀的方法是使用find和count

string search_item("Alain"); nauto entries = authors.count(search_item); nauto iter = authors.find(search_item); nnwhile(entries) n{ n cout << iter->second << endl; n ++iter; n --entries; n} n

另一種方法是使用lower_bound和upper_bound來解決

  • lower_bound返回的迭代器指向第一個具有給定關鍵字的元素
  • upper_bound返回的迭代器指向最後一個匹配給定關鍵字的元素之後的位置

如果元素不在容器中,則lower_bound和upper_bound會返回相等的迭代器——指向一個不影響排序的可插入位置

for(auto beg = authors.lower_bound(search_item),nend = authors.upper_bound(search_item);nbeg != end; ++beg) n{ n cout << beg->second << endl; n} n

這裡結束條件beg != end用的很巧妙

還可以使用equal_range函數

它接受一個關鍵字,返回一個迭代器pair

for(auto pos = authors.equal_range(search_item); pos.first != pos.second; ++pos.first) n{ n cout << pos.first->second << endl; n} n

一個單詞轉換的map

很精典的一個例子,就不再摘抄了。P391

END

微信公眾號, 馬志峰的編程筆記

專註做好一件事,每天早起學習編程1.5小時並輸出筆記。

與其去羨慕高手裝逼,不如來見證菜鳥成長!


推薦閱讀:

當刷題遇見吐槽和涼席椅墊,完美!
15個C++項目列表
說說 C++ 的 Concept
[譯] C++中帶狀態元編程黑科技(二):實現常量表達式計數器
C++模板元編程--replace_type<>

TAG:C | CPrimer |