如需轉載,請註明出處。
序列容器是管理數據的寶貴工具,但對大多數應用程序而言,序列容器不提供方便的數據訪問機制。舉個簡單的示例,當我們用它處理姓名和地址時,在這種場景下,序列容器可能並不能如我們所願。一種典型的方法是通過名稱來尋找地址。如果記錄保存在序列容器中,就只能通過搜索得到這些數據。相比而言,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()函數用於交換兩個映射的內容,但映射必須是相同的類型,儘管大小可能不同。