STL教程(七)——map

如需轉載,請註明出處。

序列容器是管理數據的寶貴工具,但對大多數應用程序而言,序列容器不提供方便的數據訪問機制。舉個簡單的示例,當我們用它處理姓名和地址時,在這種場景下,序列容器可能並不能如我們所願。一種典型的方法是通過名稱來尋找地址。如果記錄保存在序列容器中,就只能通過搜索得到這些數據。相比而言,map 容器提供了一種更有效的存儲和訪問數據的方法。

map 容器是關聯容器的一種。在關聯容器中,對象的位置取決於和它關聯的鍵的值。鍵可以是基本類型,也可以是類類型。字符串經常被用來作爲鍵,如果想要保存姓名和地址的記錄,就可以這麼使用。名稱通常可能是一個或多個字符串。關聯容器中的對象位置的確定取決於容器中的鍵的類型,而且對於特定容器類型的內部組織方式,不同的 STL 有不同的實現。

map<K,T> 類模板定義在 map 文件頭中,它定義了一個保存 T 類型對象的 map,每個 T 類型的對象都有一個關聯的 K 類型的鍵。容器內對象的位置是通過比較鍵決定的。可以用適當的鍵值從 map 容器中檢索對象。圖 1 展示了一個用名稱作爲鍵的 map<K,T> 容器,對象是整數值,用來表示年齡。

不要因爲 map 使用 less<K> 對元素排序就被誤導,這些元素並沒有被組織成一個簡單的有序序列,STL map 容器對元素的組織方式並沒有具體要求,但元素一般都會保存在一個平衡二叉樹中。容器中的元素被組織成一個平衡二叉樹,因而樹的高度——根節點和葉節點之間的高度是最低的。如果每個節點的左子樹和右子樹的高度差不超過 1,那麼可以說這棵二叉樹就是平衡的。圖 2 展示了圖 1 所表示的 map 容器可能的平衡二叉樹。

圖 2 所示的樹有 3 層,所以從根節點開始,找到任意的元素最多需要 3 步。這裏選擇的根節點可以使樹的高度最小,而且對於每個父節點來說,它的鍵值大於它的左子節點,但小於它的右子節點。爲了保持二叉樹的平衡,當添加一個新的元素時,可能會導致根節點發生改變。所以顯然,在添加新元素時,爲了保持樹的平衡,會產生一些額外的開銷。作爲回報,容器中的元素越多,相對於線性排列和非平衡樹,平衡樹組織元素的效率也越高。從包含 n 個元素的平衡二叉樹中檢索一個隨機元素所需的時間爲 O(log2n),從序列中檢索元素所需的時間爲 O(n)。

注意,O(n) 計算時間隨着參數的增加而增加。O 被認爲是有序的,O(n) 表明線性執行時間在以 n 增加。O(log2n) 計算時間遠沒有 n 增加得快,因爲它是以 log2n 計算的。

與Map相關的一些基本函數:

begin() - 返回map中第一個元素的迭代器
end() - 返回map中最後一個元素後面的理論元素的迭代器
size() - 返回map中元素的數量
max_size() - 返回map可容納的最大元素數
empty() - 返回map是否爲空
insert(keyvalue,mapvalue) - 向map添加新元素
erase(iterator position) - 刪除迭代器指向的位置處的元素
erase(const g) - 從map中刪除鍵值“g”
clear() - 從map中刪除所有元素

#include <iostream> 
#include <iterator> 
#include <map> 

using namespace std; 

int main() 
{ 

	// empty map container 
	map<int, int> gquiz1; 

	// insert elements in random order 
	gquiz1.insert(pair<int, int>(1, 40)); 
	gquiz1.insert(pair<int, int>(2, 30)); 
	gquiz1.insert(pair<int, int>(3, 60)); 
	gquiz1.insert(pair<int, int>(4, 20)); 
	gquiz1.insert(pair<int, int>(5, 50)); 
	gquiz1.insert(pair<int, int>(6, 50)); 
	gquiz1.insert(pair<int, int>(7, 10)); 

	// printing map gquiz1 
	map<int, int>::iterator itr; 
	cout << "\nThe map gquiz1 is : \n"; 
	cout << "\tKEY\tELEMENT\n"; 
	for (itr = gquiz1.begin(); itr != gquiz1.end(); ++itr) { 
		cout << '\t' << itr->first 
			<< '\t' << itr->second << '\n'; 
	} 
	cout << endl; 

	// assigning the elements from gquiz1 to gquiz2 
	map<int, int> gquiz2(gquiz1.begin(), gquiz1.end()); 

	// print all elements of the map gquiz2 
	cout << "\nThe map gquiz2 after"
		<< " assign from gquiz1 is : \n"; 
	cout << "\tKEY\tELEMENT\n"; 
	for (itr = gquiz2.begin(); itr != gquiz2.end(); ++itr) { 
		cout << '\t' << itr->first 
			<< '\t' << itr->second << '\n'; 
	} 
	cout << endl; 

	// remove all elements up to 
	// element with key=3 in gquiz2 
	cout << "\ngquiz2 after removal of"
			" elements less than key=3 : \n"; 
	cout << "\tKEY\tELEMENT\n"; 
	gquiz2.erase(gquiz2.begin(), gquiz2.find(3)); 
	for (itr = gquiz2.begin(); itr != gquiz2.end(); ++itr) { 
		cout << '\t' << itr->first 
			<< '\t' << itr->second << '\n'; 
	} 

	// remove all elements with key = 4 
	int num; 
	num = gquiz2.erase(4); 
	cout << "\ngquiz2.erase(4) : "; 
	cout << num << " removed \n"; 
	cout << "\tKEY\tELEMENT\n"; 
	for (itr = gquiz2.begin(); itr != gquiz2.end(); ++itr) { 
		cout << '\t' << itr->first 
			<< '\t' << itr->second << '\n'; 
	} 

	cout << endl; 

	// lower bound and upper bound for map gquiz1 key = 5 
	cout << "gquiz1.lower_bound(5) : "
		<< "\tKEY = "; 
	cout << gquiz1.lower_bound(5)->first << '\t'; 
	cout << "\tELEMENT = "
		<< gquiz1.lower_bound(5)->second << endl; 
	cout << "gquiz1.upper_bound(5) : "
		<< "\tKEY = "; 
	cout << gquiz1.upper_bound(5)->first << '\t'; 
	cout << "\tELEMENT = "
		<< gquiz1.upper_bound(5)->second << endl; 

	return 0; 
} 

輸出:

The map gquiz1 is : 
	KEY	ELEMENT
	1	40
	2	30
	3	60
	4	20
	5	50
	6	50
	7	10


The map gquiz2 after assign from gquiz1 is : 
	KEY	ELEMENT
	1	40
	2	30
	3	60
	4	20
	5	50
	6	50
	7	10


gquiz2 after removal of elements less than key=3 : 
	KEY	ELEMENT
	3	60
	4	20
	5	50
	6	50
	7	10

gquiz2.erase(4) : 1 removed 
	KEY	ELEMENT
	3	60
	5	50
	6	50
	7	10

gquiz1.lower_bound(5) : 	KEY = 5		ELEMENT = 50
gquiz1.upper_bound(5) : 	KEY = 6		ELEMENT = 50

Map的所有函數列表:

insert()-在map容器中插入具有特定鍵的元素。 。
count()-返回映射中鍵值爲'g'的元素的匹配數。
equal_range()-返回對的迭代器。該對指的是一個範圍的邊界,該範圍包括容器中具有等於k的鍵的所有元素。
erase()-用於從容器中擦除元素。
rend()-返回一個反向迭代器,它指向映射中第一個鍵值對之前的理論元素(被認爲是它的反向結束)。
rbegin()-返回一個反向迭代器,它指向map的最後一個元素。
find()- 如果找到,則返回映射中具有鍵值“g”的元素的迭代器,否則返回迭代器結束。
crbegin()返回一個常量反向迭代器,引用映射容器中的最後一個元素。

crend()返回一個常量反向迭代器,指向map中第一個元素之前的理論元素。
cbegin()返回一個引用映射容器中第一個元素的常量迭代器。

cend()返回一個常量迭代器,指向multimap中最後一個元素後面的理論元素。
emplace() - 將鍵及其元素插入映射容器中。
max_size()-返回map容器可容納的最大元素數。
upper_bound()- 返回第一個元素的迭代器,該元素等效於具有鍵值'g'的映射值,或者肯定會在map中具有鍵值'g'的元素之後返回
operator = -將容器的內容分配給不同的容器,替換其當前內容。
lower_bound()- 返回第一個元素的迭代器,該元素等效於具有鍵值'g'的映射值,或者肯定不會在映射中具有鍵值'g'的元素之前。
emplace_hint()- 使用給定的提示將鍵及其元素插入到映射容器中。
value_comp()-返回確定map中元素排序方式的對象(默認情況下爲“<”)。
key_comp()函數STL-返回確定map中元素排序方式的對象(默認情況下爲“<”)。
size()-返回map中元素的數量。
empty()-返回map是否爲空。
begin()返回映射中第一個元素的迭代器。

end()將迭代器返回到map中最後一個元素後面的理論元素
operator [] -此運算符用於引用運算符內給定位置的元素。
clear()-從地圖中刪除所有元素。
at()函數用於返回與鍵k相關聯的元素的引用。

swap()函數用於交換兩個映射的內容,但映射必須是相同的類型,儘管大小可能不同。

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