map&pair相關用法
tips:map是一個關聯容器,而pair是一個數據的模板類型,兩者其實並不屬於同一類,但是放在一起,方便記憶理解
map
1,map簡介
map是STL的一個關聯容器,它提供一對一的hash。
- 第一個可以稱為關鍵字(key),每個關鍵字只能在map中出現一次;
- 第二個可能稱為該關鍵字的值(value);
map以模板(泛型)方式實現,可以存儲任意類型的數據,包括使用者自定義的數據類型。Map主要用於資料一對一映射(one-to-one)的情況,map內部的實現自建一顆紅黑樹,這顆樹具有對數據自動排序的功能。在map內部所有的數據都是有序的,后邊我們會見識到有序的好處。比如一個班級中,每個學生的學號跟他的姓名就存在著一對一映射的關系。
2,map的功能
自動建立key - value的對應。key 和 value可以是任意你需要的類型。
3,使用map
使用map得包含map類所在的頭文件
#include
map對象是模板類,需要關鍵字和存儲對象兩個模板參數:
std:map<int, string> personnel;
這樣就定義了一個用int作為索引,並擁有相關聯的指向string的指針.
為了使用方便,可以對模板類進行一下類型定義,
typedef map<int,CString> UDT_MAP_INT_CSTRING;
UDT_MAP_INT_CSTRING enumMap;
4,map的構造函數
map共提供了6個構造函數,這塊涉及到內存分配器這些東西,略過不表,在下面我們將接觸到一些map的構造方法,這里要說下的就是,我們通常用如下方法構造一個map:
map<int, string> mapStudent;
5,插入元素
// 定義一個map對象
map<int, string> mapStudent;
// 第一種 用insert函數插入pair
mapStudent.insert(pair<int, string>(000, "student_zero"));
// 第二種 用insert函數插入value_type數據
mapStudent.insert(map<int, string>::value_type(001, "student_one"));
// 第三種 用"array"方式插入(個人感覺這個更方便,輸出也可以用此形式)
mapStudent[123] = "student_first";
mapStudent[456] = "student_second";
以上三種用法,雖然都可以實現數據的插入,但是它們是有區別的,當然了第一種和第二種在效果上是完成一樣的,用insert函數插入數據,在數據的 插入上涉及到集合的唯一性這個概念,即當map中有這個關鍵字時,insert操作是不能在插入數據的,但是用數組方式就不同了,它可以覆蓋以前該關鍵字對 應的值,用程序說明如下:
mapStudent.insert(map<int, string>::value_type (001, "student_one"));
mapStudent.insert(map<int, string>::value_type (001, "student_two"));
上面這兩條語句執行后,map中001這個關鍵字對應的值是“student_one”,第二條語句並沒有生效,那么這就涉及到我們怎么知道insert語句是否插入成功的問題了,可以用pair來獲得是否插入成功,程序如下
// 構造定義,返回一個pair對象
pair<iterator,bool> insert (const value_type& val);
pair<map<int, string>::iterator, bool> Insert_Pair;
Insert_Pair = mapStudent.insert(map<int, string>::value_type (001, "student_one"));
if(!Insert_Pair.second)
cout << ""Error insert new element" << endl;
我們通過pair的第二個變量來知道是否插入成功,它的第一個變量返回的是一個map的迭代器,如果插入成功的話Insert_Pair.second應該是true的,否則為false。
6, 查找元素
當所查找的關鍵key出現時,它返回數據所在對象的位置,如果沒有,返回iter與end函數的值相同。
// find 返回迭代器指向當前查找元素的位置否則返回map::end()位置
iter = mapStudent.find("123");
if(iter != mapStudent.end())
cout<<"Find, the value is"<<iter->second<<endl;
else
cout<<"Do not Find"<<endl;
7, 刪除與清空元素
//迭代器刪除
iter = mapStudent.find("123");
mapStudent.erase(iter);
//用關鍵字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
//用迭代器范圍刪除 : 把整個map清空
mapStudent.erase(mapStudent.begin(), mapStudent.end());
//等同於mapStudent.clear()
8,map的大小
在往map里面插入了數據,我們怎么知道當前已經插入了多少數據呢,可以用size函數,用法如下:
int nSize = mapStudent.size();
9,map的基本操作函數:
C++ maps是一種關聯式容器,包含“關鍵字/值”對
begin() 返回指向map頭部的迭代器
clear() 刪除所有元素
count() 返回指定元素出現的次數
empty() 如果map為空則返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊條目的迭代器對
erase() 刪除一個元素
find() 查找一個元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比較元素key的函數
lower_bound() 返回鍵值>=給定元素的第一個位置
max_size() 返回可以容納的最大元素個數
rbegin() 返回一個指向map尾部的逆向迭代器
rend() 返回一個指向map頭部的逆向迭代器
size() 返回map中元素的個數
swap() 交換兩個map
upper_bound() 返回鍵值>給定元素的第一個位置
value_comp() 返回比較元素value的函數
pair
1,pair的應用
pair是將2個數據組合成一組數據,當需要這樣的需求時就可以使用pair,如stl中的map就是將key和value放在一起來保存。另一個應用是,當一個函數需要返回2個數據的時候,可以選擇pair。 pair的實現是一個結構體,主要的兩個成員變量是first second 因為是使用struct不是class,所以可以直接使用pair的成員變量。
其標准庫類型--pair類型定義在#include
類模板:template<class T1,class T2> struct pair
參數:T1是第一個值的數據類型,T2是第二個值的數據類型。
功能:pair將一對值(T1和T2)組合成一個值,
這一對值可以具有不同的數據類型(T1和T2),
兩個值可以分別用pair的兩個公有函數first和second訪問。
定義(構造函數):
pair<T1, T2> p1; //創建一個空的pair對象(使用默認構造),它的兩個元素分別是T1和T2類型,采用值初始化。
pair<T1, T2> p1(v1, v2); //創建一個pair對象,它的兩個元素分別是T1和T2類型,其中first成員初始化為v1,second成員初始化為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; // 如果兩個對象的first和second依次相等,則這兩個對象相等;該運算使用元素的==操作符。
p1.first; // 返回對象p1中名為first的公有數據成員
p1.second; // 返回對象p1中名為second的公有數據成員
2,pair的創建和初始化
pair包含兩個數值,與容器一樣,pair也是一種模板類型。但是又與之前介紹的容器不同;
在創建pair對象時,必須提供兩個類型名,兩個對應的類型名的類型不必相同
pair<string, string> anon; // 創建一個空對象anon,兩個元素類型都是string
pair<string, int> word_count; // 創建一個空對象 word_count, 兩個元素類型分別是string和int類型
pair<string, vector<int> > line; // 創建一個空對象line,兩個元素類型分別是string和vector類型
當然也可以在定義時進行成員初始化:
pair<string, string> author("James","Joy"); // 創建一個author對象,兩個元素類型分別為string類型,並默認初始值為James和Joy。
pair<string, int> name_age("Tom", 18);
pair<string, int> name_age2(name_age); // 拷貝構造初始化
pair類型的使用相當的繁瑣,如果定義多個相同的pair類型對象,可以使用typedef簡化聲明:
typedef pair<string,string> Author;
Author proust("March","Proust");
Author Joy("James","Joy");
變量間賦值:
pair<int, double> p1(1, 1.2);
pair<int, double> p2 = p1; // copy construction to initialize object
pair<int, double> p3;
p3 = p1; // operator =
3,pair對象的操作
訪問兩個元素操作可以通過first和sencond訪問:
pair<int ,double> p1;
p1.first = 1;
p1.second = 2.5;
cout<<p1.first<<' '<<p1.second<<endl;
//輸出結果:1 2.5
string firstBook;
if(author.first=="James" && author.second=="Joy")
firstBook="Stephen Hero";
4,生成新的pair對象
還可以利用make_pair創建新的pair對象:
pair<int, double> p1;
p1 = make_pair(1, 1.2);
cout << p1.first << p1.second << endl;
//output: 1 1.2
int a = 8;
string m = "James";
pair<int, string> newone;
newone = make_pair(a, m);
cout << newone.first << newone.second << endl;
//output: 8 James
5,通過tie獲取pair元素值
在某些清況函數會以pair對象作為返回值時,可以直接通過std::tie進行接收。比如:
std::pair<std::string, int> getPreson() {
return std::make_pair("Sven", 25);
}
int main(int argc, char **argv) {
std::string name;
int ages;
std::tie(name, ages) = getPreson();
std::cout << "name: " << name << ", ages: " << ages << std::endl;
return 0;
}
以上摘自CSDN博主「sevencheng798」的原創文章。原文鏈接:寧要是覺得看我的不方便請點這里
總結
pair:
- pair的類型:pair是一種模版類型。每個pair 可以存儲兩個值。這兩種值的類型沒有限制,也可以將自己寫的類放進去。
- pair 應用:如果一個函數有兩個返回值的話,如果是相同類型,就可以用數組返回,如果是不同類型,兩個屬性的話,就可以用pair 進行操作,有多個屬性的時候 ,可以使用tuple。
map:
map可以當做一個容器(裝載具有一定格式的數據);pair可以理解為元素(放入到容器的的每個個體),pair並沒有單獨行動的典型用法,正常都是配合map來使用(即把pair這個元素插入到map這個容器里面)
注意map關鍵作用是一一映射,且不允許有兩個相同的關鍵字,而pair可以
部分理解可能存在不妥,歡迎指正