C Primer第五版筆記 關聯容器

2021-08-21 10:17:27 字數 3715 閱讀 6547

一、型別

關聯容器支援高效的關鍵字查詢和訪問,標準庫中兩個主要的關聯容器是map和set。map中的元素是鍵值對關鍵字表示索引。set中每個元素只包含乙個關鍵字,set支援高效的關鍵字查詢。

關聯容器根據三個特性可以分為8種:1、set還是map;2、關鍵字是否可以重複,允許重複的容器名字中都包含單詞「multi」;3、元素是否有序儲存,無序儲存的容器名字中都包含單詞「unordered」。

型別map和multimap定義在標頭檔案map中;set和muitlset定義在標頭檔案set中;無序容器則定義在unordered_map或unordered_set中。

關聯容器不支援順序容器的位置相關的操作,例如push_back等,原因是關聯容器中的元素是根據關鍵字儲存的,這些操作對關聯容器就失去了意義。

二、使用

1、使用map

定義map時需指定關鍵字和值的型別,在訪問的時候通過first和second來訪問元素的值,例子:

//統計每個單詞在輸入中出現的次數

map word_count;

string word;

while(cin >> word)

++word_count[word];

}for(const

auto &w : word_count);

string word;

while(cin >> word)

//只統計不在set中的單詞

if(exclude.find(word) == exclude.end())

}for(const

auto &w : word_count)

set iset(v.cbegin(),v.cend());

multiset

imset(v.cbegin(),v.cend());

cout

cout

::value_type v1; //v1是string型別

set::key_type v2; //v2是string型別,與value_type相同

map::value_type m1; //m1是pair

map::key_type m2; //m2是string

map

1.迭代器

當解引用乙個關聯容器迭代器的時候,我們會得到乙個型別為容器的value_type值的引用。

//*map_it是指向word_count第乙個元素的迭代器

auto map_it = word_count.begin();

cout

cout

second的值

//set的迭代器也是const的

set::iterator set_it = iset.begin();

2.新增元素

關聯容器的insert成員想容器中新增乙個元素或乙個元素範圍。由於map和set包含不重複的關鍵字,所以插入乙個已經存在的元素對容器沒有任何影響。

#include 

#include

#include

#include

using

namespace

std;

int main();

set s;

s.insert(v.cbegin(),v.cend());

cout

s.insert();

cout

return

0;}

向map中新增元素的時候,需記住元素型別是pair。

//新增的四種方法

map m;

m.insert();

m.insert(make_pair("alex",19));

m.insert(pair("siri",20));

m.insert(map

::value_type("james",22));

map呼叫insert方法後返回值是乙個pair,告訴我們是否插入成功,這個pair的first成員是map的迭代器,指向具有指定關鍵字的元素(還是個pair);second成員是乙個bool值,如果插入時關鍵字已經在容器中,insert什麼事也不做,並且second的bool值為false,如果關鍵字不存在,插入後返回second中bool的值為true,表示插入成功。

向multiset或multimap新增元素方法類似,但是返回值不需要返回bool值,只需要返回指向新元素的迭代器。

3.刪除元素

關聯容器定義了三個版本的erase,與順序容器一樣可以傳遞給erase乙個迭代器或是乙個迭代器對來刪除乙個元素或者刪除乙個元素範圍,指定元素被刪除,返回值為void。

額外的乙個erase操作是接受乙個key_type引數,刪除所有匹配給定關鍵字的元素,返回實際刪除的元素的數量

4.map的下標操作

map和unordered_map提供了下標運算子和乙個對應的at函式。set不支援下標,因為沒有與關鍵字相對應的值。不能對multimap或乙個unordered_multimap進行下標操作,因為乙個關鍵字可能繫結多個值。

與其他下標運算子不同的是,如果關鍵字並不在map中,會為他建立乙個元素插入到map中,並進行值初始化:

map

m;m["anna"] = 1;

//搜尋關鍵值為anna的元素,未找到;

//將新鍵值對插入m中,關鍵字型別是const string,儲存"anna",值進行初始化;

//提取新插入的元素,將1賦值給它

5.訪問元素

主要講的是兩個函式,find()和count(),如果只是關心元素是否在容器中,那麼find是最好的選擇。但對於可以重複關鍵字的容器,count還會統計有多少個關鍵字重複的元素,當不需要計數的時候,最好還是使用find()。

set

s = ;

s.find(1); //返回乙個迭代器,指向第乙個key = 1 的元素

s.find(11); //返回乙個迭代器,指向s.end()

s.count(1); //返回1

s.count(11); //返回0

在multiset和multimap中查詢的時候有乙個特性很重要,那就是如果存在相同關鍵字的元素,這些元素會相鄰儲存。因此find和count同時使用可能會到達效果:
//查詢乙個作者寫的書,authors是定義好的multimap

string name("ernest miller hemingway"); //要查詢的作者

auto num = authors.count(name); //書的數量

auto it = authors.find(name); //作者的第一本書

//用迴圈查詢作者所有的書

while(num){

cout

auto u = authors.upper_bound(name); //指向最後乙個

l != u;

l++){

cout

pos.first != pos.second;

++pos.first){

coutsecond

<

C Primer第五版筆記 動態陣列

allocator類 為了讓new分配乙個物件陣列,需要在型別名後跟方括號,括號中是分配物件的數目,該數目必須是整型,但不必是常量 new t 分配的記憶體並不是得到乙個陣列,而是得到乙個陣列元素型別的指標,因此不能對動態陣列呼叫begin和end 與普通陣列不同的是,普通陣列不能定義長度為0的陣列...

C Primer第五版筆記 拷貝控制

拷貝賦值函式 析構函式 三 五法則 default和阻止拷貝 乙個類通過定義五種特殊的成員函式來控制其拷貝 賦值 移動以及銷毀操作 拷貝建構函式 拷貝賦值運算子 移動建構函式 移動賦值運算子和析構函式。這些操作都是拷貝控制操作。當實現自己的類的時候要想好在做這些操作時的規則,因為編譯器通常會自動生成...

C Primer第五版筆記 虛函式

當我們使用基類的引用或指標呼叫乙個虛成員函式時會發生動態繫結,知道執行時才會知道到底呼叫了哪個版本的虛函式,因此所有的虛函式都必須有定義。對虛函式的呼叫可能在執行時才被解析 物件導向程式設計的核心思想是多型性 polymorphism 多型性這個詞源於希臘語,其含義是 多種形態 引用或指標的靜態型別...