《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
通常不對關聯容器使用泛型演算法
- 關鍵字是const的,很多修改或重排容器元素的演算法不適用
- 對於只讀演算法,很多都要搜索序列,使用關聯容器專用的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<>
