關聯容器 - 1【C++ Primer 學習筆記 - 第十章】

關聯容器的類型:
1、map    關聯數組,元素通過鍵來存儲和讀取,以鍵值(key-value)對的形式組織
2、set      大小可變的集合,支持通過鍵實現的快速讀取
3、multimap    支持同一個鍵多次出現的 map 類型
4、multiset     支持同一個鍵多次出現的 set 類型

set 和 map 類型的對象所包含的元素都具有不同的鍵不允許爲同一個鍵添加第二個元素
如果一個鍵必須對應多個實例,則需要使用 multimap 或者 mulitset 類型


定義在 utilitiy 頭文件中的 pair 類型

pair 類型提供的操作
pair<T1, T2> p1 創建一個空的 pair 對象,
它的兩個元素分別是 T1 和 T2 類型,採用值初始化
pair<T1, T2> p1(v1, v2) 創建一個空的 pair 對象
兩個元素類型分別是 T1 和 T2 類型,
第一個初始化爲 v1,第二個初始化爲 v2
make_pair(v1, v2) 以 v1 和 v2 值創建一個新的 pair 對象, 其元素類型分別是 v1、v2的類型
p1 < p2 pair 對象之間的小於運算
p1.first < p2.first 或者 !(p2.first < p1.first) && p1.second<p2.second,則:true
p1 == p2 p1、p2 的 first 和 second 成員依次相等,則 p1、p2 相等
p.first 返回 p 中名爲 first 的數據成員
p.second 返回 p 中名爲 second 的數據成員














pair 包含2個數據值。與容器一樣,是一種模板類型。
pair 類的成員都是公有的,可以直接訪問數據,分別命名爲 first、 second

pair<string, vector<int> > word_count;
pair<string, string> author("James", "Joyce");
typedef pair<string, string> Author;
Author zhang("Zhang", "San");
Author li("Li", "Si");

if(zhang.first=="Zhang" && zhang.second=="San")
	cout << "Found Author ZhangSan" << endl;

string first = "Mo", second = "Yan";
Author mo = make_pair(first, second);


map 的構造函數
map<k, v> m; 創建一個名爲 m 的空 map 對象,鍵值類型分別爲 k、v
map<k, v> m(m2) 創建 m2 的副本 m, m和m2 必須有相同的鍵類型、值類型
map<k, v> m(b, e) 創建 map 類型的對象 m,存儲迭代器 b 和 e 標記的範圍內所有元素的副本
元素類型必須能夠轉換爲 pair<const k, v>






鍵類型必須定義 < 操作符,而且是嚴格弱排序的,即,鍵類型數據上的小於關係。


map 類定義的類型
map<K, V>::key_type 在 map 容器中,用作索引的鍵的類型
map<K, V>::mapped_type 在 map 容器中,鍵所關聯的值的類型
map<K, V>::value_type pair 類型,
first 元素具有 const map<K,V>::key_type 類型
second 元素具有 map<K,V>::mapped_type 類型





value_type 是 pair 類型,值成員可以修改,鍵成員不能修改

map 類額外定義的類型別名,
map<string, int>::key_type 是 string 類型,
map<string, int>::value_type 是 int 類型


map<string, int> word_count;
word_count["Anna"] = 1;
// 上述代碼,執行過程:
// 1、在word_count 查找 "Anna",未找到
// 2、插入新的鍵值對,鍵爲"Anna",值初始化 0
// 3、讀取新插入的鍵值對,然後賦值爲1
// 用下標訪問 map 的情況,不同於數組和vector,
// 下標訪問 map 中不存在的元素,將導致在該 map 中增加一個響應元素

vector 的下標操作返回的類型,和 vector迭代器解引用 獲得的類型相同。
但是,
map 的下標操作返回左值,是 mapped_type 類型,
而 map 迭代器返回 value_type 類型,
包含 const key_type 、  mapped_type 的 pair 對象


// 此例演示了 map 類型,特殊的下標行爲在編程中的意義
map<string, int> word_count;
string word;
while(cin >> word)
	++word_count[word];



map 容器提供的 insert 操作
m.insert(e) e 是一個 m 上的 value_type 類型的值。
如果 e.first 不在 m 中,則,插入新元素,值爲 e.second
如果 e.first 已存在,m 不變。
該函數返回一個pair 類型的對象,
包含,指向鍵爲 e.first 的元素的 map 迭代器,
和 一個bool 類型的對象,表示是否成功插入元素
m.insert(beg, end) beg 和 end 是標記元素範圍的迭代器,
其中元素必須爲 m.value_type 類型的鍵值對。
對於該範圍內的所有元素,如果它的鍵在 m 中不存在,
則插入該鍵值對。返回 void 類型
m.insert(iter, e) e 是一個 m 上的  value_type 類型的鍵值對。
如果 e.first 在 m 中不存在,則創建新元素,
並以迭代器 iter 爲起點搜索新元素存儲的位置。
返回一個迭代器,指向 m 中具有給定鍵的元素

















map<string, int> word_count;
word_count.insert(map<string, int>::value_type("Anna", 1));

// 此處 "Anna" 鍵,已經存在,不會作任何操作
word_count.insert(make_pair("Anna", 1));
typedef map<string, int>::value_type valueType;
word_count.insert(valueType("Zhang", 2));

string word;
while(cin >> word)
{
	pair<map<string, int>::iterator, bool> ret = word_count.insert(make_pair(word, 1));

	// 已存在,插入失敗,ret.second 爲 false
	if(!ret.second)
		++ret.first->second;
		// ret.first 類型爲 map<string, int>::iterator
		// 該迭代器指向 map<string, int>::value_type		
}


map 中的查詢操作

m.count(k)
返回 m 中 k 的出現次數,只能是0 或者 1

m.find(k)
如果 m 中存在按 k 索引的元素,則返回指向該元素的迭代器。否則,返回超出末端迭代器

map<string, int> word_count;
int occurs = 0;

// 此處實際上使用了2次查找
// 因爲下標操作,總是會查找一次
if(word_count.count("fooBar"))
	occurs = word_count["fooBar"];

// 此處只查找了一次
map<string, int>::iterator iter = word_count.find("fooBar2");
if(iter != word_count.end())
	occurs = iter->second;


從 map 中刪除元素
m.erase(k)
刪除 m 中 鍵爲 k 的元素。返回 size_type 類型,表示刪除的個數。只能是0 或者 1

m.erase(p)
刪除 m 中迭代器 p 所指向的元素。p 指向的元素必須存在,且不能是 m.end()。返回 void

m.erase(b, e)
刪除由迭代器b 和 e 標記的範圍。返回 void


map<string, int> word_count;
word_count.insert(make_pair("z", 1));
word_count.insert(make_pair("a", 2));
map<string, int>::iterator iter = word_count.begin();
while( iter!= word_count.end())
{
	cout << "Key: " << iter->first << ", ";
	cout << "Value: " << iter->second << endl;
	++iter;
}
// 結果是:
// Key: a, Value: 2
// Key: z, Value: 1
// 說明,使用迭代器遍歷 map 容器時,迭代器指向的元素按照 鍵的升序排列


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章