關聯式容器的一種,map 容器存儲的都是 pair 對象,也就是用 pair 類模板創建的鍵值對。其中,各個鍵值對的鍵和值可以是任意數據類型,包括 C++ 基本數據類型(int、double 等)、結構體或類自定義的類型。
通常情況下,map 容器中存儲的各個鍵值對都選用 string 字符串作爲鍵的類型。
map 容器
- 容器會自動根據各鍵值對的鍵的大小,對鍵值對做升序排序(默認)。
即map 容器選用std::less對鍵值對升序排序。也可以手動指定 map 容器的排序規則(比如std::greater),也可以自定義排序規則。 - 存儲的鍵值對,鍵的值都是唯一的、獨一無二的。
一、map 容器定義
引入#include <map>
map 容器的模板定義
template < class Key, // 指定鍵(key)的類型
class T, // 指定值(value)的類型
class Compare = less<Key>, // 指定排序規則(默認升序排列)
class Alloc = allocator<pair<const Key,T> > // 指定分配器對象的類型
> class map;
map 容器模板有 4 個參數,其中後 2 個參數都設有默認值。
我們只需要設定前 2 個參數的值,有些場景可能會用到第 3 個參數,但最後一個參數幾乎不會用到。
創建C++ map容器的幾種方法
map 容器的模板類中包含多種構造函數,下面就幾種常用的創建 map 容器的方法:
map 容器中存儲的鍵值對,其本質都是 pair 類模板創建的 pair 對象
map 容器的拷貝(複製)構造函數,即可成功創建一個和 myMap 完全一樣的 newMap 容器。
移動構造函數:當有臨時的 map 對象作爲參數,傳遞給要初始化的 map 容器時,此時就會調用移動構造函數。
std::map<std::string, int> myMap; //默認構造函數
std::map<std::string, int> myMap{ {"zhangsan",100},{"lisi",90} }; //聲明同時初始化
// pair 類模板創建
std::map<std::string, int>myMap{std::make_pair("yuwen",80),std::make_pair("shuxue",70)};
//調用拷貝(複製)構造函數,創建的 newMap 容器與myMap 完全一樣。
std::map<std::string, int>newMap(myMap);
// 取已建 map 容器中指定區域內的鍵值對,創建並初始化新的 map 容器
std::map<std::string, int>newMap(++myMap.begin(), myMap.end());
//手動修改了 myMap 容器爲降序排序
std::map<std::string, int, std::greater<std::string> >myMap{ {"zhangsan",100},{"lisi",90} };
//移動構造函數
std::map<std::string,int> disMap() {
std::map<std::string, int>tempMap{ {"zhangsan",100},{"lisi",90} };
return tempMap;
}
//調用 map 類模板的移動構造函數創建 newMap 容器
std::map<std::string, int>newMap(disMap());
注意:無論是調用複製構造函數還是調用拷貝構造函數,都必須保證這 2 個容器的類型完全一致。
二、map 容器成員方法
成員方法 | 功能 |
---|---|
begin() | 返回指向容器中 (已排好序)第一個鍵值對的雙向迭代器。如果 map 容器用 const 限定,則該方法返回的是 const 類型的雙向迭代器。 |
end() | 返回指向容器 (已排好序)最後一個元素所在位置後一個位置的雙向迭代器,通常和 begin() 結合使用。如果 map 容器用 const 限定,則該方法返回的是 const 類型的雙向迭代器。 |
rbegin() | 功能同begin() ,則該方法返回的是 const 類型的反向雙向迭代器。 |
rend() | 功能同 end() ,則該方法返回的是 const 類型的反向雙向迭代器。 |
cbegin() | 和 begin() 功能相同,增加了 const 屬性,不能用於修改容器內存儲的鍵值對。 |
cend() | 和 end() 功能相同,增加了 const 屬性,不能用於修改容器內存儲的鍵值對。 |
crbegin() | 和 rbegin() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改容器內存儲的鍵值對。 |
crend() | 和 rend() 功能相同,只不過在其基礎上,增加了 const 屬性,不能用於修改容器內存儲的鍵值對。 |
find(key) | 在 map 容器中查找鍵爲 key 的鍵值對,如果成功找到,則返回指向該鍵值對的雙向迭代器;反之,則返回和 end() 方法一樣的迭代器。另外,如果 map 容器用 const 限定,則該方法返回的是 const 類型的雙向迭代器。 |
lower_bound(key) | 返回一個指向當前 map 容器中第一個大於或等於 key 的鍵值對的雙向迭代器。如果 map 容器用 const 限定,則該方法返回的是 const 類型的雙向迭代器。 |
upper_bound(key) | 返回一個指向當前 map 容器中第一個大於 key 的鍵值對的迭代器。如果 map 容器用 const 限定,則該方法返回的是 const 類型的雙向迭代器。 |
equal_range(key) | 該方法返回一個 pair 對象(包含 2 個雙向迭代器),其中 : pair.first == lower_bound() 方法的返回值等價, pair.second ==upper_bound() 方法的返回值等價。也就是說,該方法將返回一個範圍,該範圍中包含的鍵爲 key 的鍵值對(map 容器鍵值對唯一,因此該範圍最多包含一個鍵值對)。 |
empty() | 判斷容器是否爲空:若容器爲空,則返回 true;否則 false。 |
size() | 返回當前 map 容器中存有鍵值對的個數。 |
max_size() | 返回 map 容器所能容納鍵值對的最大個數(容器容量),不同的操作系統,其返回值亦不相同。 |
operator[ ] | map容器重載了 [ ] 運算符,只要知道 map 容器中某個鍵值對的鍵的值,就可以向獲取數組中元素那樣,通過鍵直接獲取對應的值。 |
at(key) | 找到 map 容器中 key 鍵對應的值,如果找不到,該函數會引發 out_of_range 異常。 |
insert() | 向 map 容器中插入鍵值對。 |
erase() | 刪除 map 容器指定位置、指定鍵(key)值或者指定區域內的鍵值對。 |
swap() | 交換 2 個 map 容器中存儲的鍵值對,這意味着,操作的 2 個鍵值對的類型必須相同。 |
clear() | 清空 map 容器中所有的鍵值對,即使 map 容器的 size() 爲 0。 |
emplace() | 在當前 map 容器中的指定位置處構造新鍵值對。其效果和插入鍵值對一樣,但效率更高。 |
emplace_hint() | 在本質上和 emplace() 在 map 容器中構造新鍵值對的方式是一樣的,不同之處在於,使用者必須爲該方法提供一個指示鍵值對生成位置的迭代器,並作爲該方法的第一個參數。 |
cout(key) | 在當前 map 容器中,查找鍵爲 key 的鍵值對的個數並返回。注意,由於 map 容器中各鍵值對的鍵的值是唯一的,因此該函數的返回值最大爲 1。 |
小案例:
#include "stdafx.h"
#include <map>
#include <iostream>
#include <string>
#include <functional>
using namespace std;
int main()
{
std::map<std::string, int, std::greater<std::string>> mymap;
mymap.emplace("zhangsan", 90);
mymap.emplace("lisi", 89);
mymap.emplace("wangwu", 87);
cout << "mymap.size():" << mymap.size() << endl;
for (auto it = mymap.begin(); it != mymap.end(); it++)
{
cout << it->first << " " << it->second << endl;
}
return 0;
}
報錯:C++ “greater”: 未聲明的標識符錯誤
引入頭文件:#include<functional>
即可解決
三、map 類元素刪除
map 類模板提供了 erase() 和 clear() 成員方法,可用來刪除容器中存儲的鍵值對。
erase() 有 3 種適用於不同實際場景需要的語法格式:
-
可以根據目標鍵值對位於 map 容器中的位置,實現刪除該鍵值對的目的。
//刪除 map 容器中迭代器指定位置的鍵值對
iterator erase (const_iterator position)
;
position 爲迭代器,指向要刪除的鍵值對。同時該方法會返回一個 iterator 迭代器,其指向的是刪除鍵值對之後的那個鍵值對。(等同於 end() 成員方法返回的迭代器) -
傳入目標鍵值對的 鍵,這個與python一樣。
//刪除 map 容器中鍵爲 k 的鍵值對
size_type erase (const key_type& k)
返回值爲成功刪除的鍵值對的個數; -
刪除某個指定區域內的所有鍵值對
//刪除 map 容器中位於[first,last)
區域內的所有鍵值對
iterator erase (const_iterator first, const_iterator last)
;
返回的迭代器將指向 map 容器最後一個鍵值對之後的位置(等同於 end() 成員方法返回的迭代器)。
小案例:
#include <iostream>
#include <map> // map
#include <string> // string
using namespace std;
int main() {
map<std::string, std::string>myMap{ {"zhangsan", "今天去購物"},
{"lisi", "今天去游泳"},
{"wangwu", "今天去爬山"},
{"zhaoliu", "今天去讀書"} };
map<std::string, std::string>Map02{ {"zhangsan02", "今天去購物"},
{"lisi02", "今天去游泳"},
{"wangwu02", "今天去爬山"},
{"zhaoliu02", "今天去讀書"} };
//創建一個指向要刪除的鍵值對的迭代器(這裏指向第二個鍵值對)
map<string, string>::iterator iter = ++myMap.begin();
map<string, string>::iterator ret = myMap.erase(iter); //執行刪除操作
//輸出 erase() 方法返回的迭代器指向的鍵值對(等同於 end() 成員方法返回的迭代器)
cout << ret->first << " " << ret->second << endl; // wangwu 今天去爬山
int num = myMap.erase("zhaoliu"); //執行刪除操作
cout << "num = " << num << endl; // num = 1 (成功刪除的鍵值對的個數)
map<string, string>::iterator first02 = Map02.begin();
map<string, string>::iterator last02 = --Map02.end(); //--Map02.end() 向前移一位
map<string, string>::iterator ret02 = Map02.erase(first02,last02);
cout << ret02->first << " " << ret02->second << endl; // zhaoliu02, 今天去讀書
return 0;
}
void clear() 清空容器。該方法不需要傳入任何參數,也不需要接收任何返回值。
MapName.clear();
http://c.biancheng.net/view/7187.html