C++深入分析STL中map容器的使用
1、map容器
map是C++ STL的一個(gè)關(guān)聯(lián)容器,它提供一對(duì)一的數(shù)據(jù)處理能力。其中,各個(gè)鍵值對(duì)的鍵和值可以是任意數(shù)據(jù)類型,包括 C++ 基本數(shù)據(jù)類型(int、double 等)、使用結(jié)構(gòu)體或類自定義的類型。
第一個(gè)可以稱為關(guān)鍵字(key);
第二個(gè)可能稱為該關(guān)鍵字的值(value);
該容器存儲(chǔ)的都是 pair<const K, T> 類型(其中 K 和 T 分別表示鍵和值的數(shù)據(jù)類型)的鍵值對(duì)元素。
使用 map 容器存儲(chǔ)的各個(gè)鍵值對(duì),鍵的值既不能重復(fù)也不能被修改。換句話說(shuō),map 容器中存儲(chǔ)的各個(gè)鍵值對(duì)不僅鍵的值獨(dú)一無(wú)二,鍵的類型也會(huì)用 const 修飾,這意味著只要鍵值對(duì)被存儲(chǔ)到 map 容器中,其鍵的值將不能再做任何修改。
2、map容器原理
map容器的實(shí)現(xiàn)是自建了一顆紅黑樹(shù),這顆樹(shù)具有對(duì)數(shù)據(jù)自動(dòng)排序的功能,在map內(nèi)部所有的數(shù)據(jù)都是有序的
3、map容器函數(shù)接口
begin()返回指向map頭部的迭代器
clear()刪除所有元素
count()返回指定元素出現(xiàn)的次數(shù)
empty()如果map為空則返回true
end()返回指向map末尾的迭代器
equal_range()返回特殊條目的迭代器對(duì)
erase()刪除一個(gè)元素
find()查找一個(gè)元素
get_allocator()返回map的配置器
insert()插入元素
key_comp()返回比較元素key的函數(shù)
lower_bound()返回鍵值>=給定元素的第一個(gè)位置
max_size()返回可以容納的最大元素個(gè)數(shù)
rbegin()返回一個(gè)指向map尾部的逆向迭代器
rend()返回一個(gè)指向map頭部的逆向迭代器
size()返回map中元素的個(gè)數(shù)
swap()交換兩個(gè)map
upper_bound()返回鍵值>給定元素的第一個(gè)位置
value_comp()返回比較元素value的函數(shù)
#include<map>
map<key, value> m;//創(chuàng)建一個(gè)名為m的空map對(duì)象,其鍵和值的類型分別為key和value。
map<key, value> m(m2);//創(chuàng)建m2的副本m,m與m2必須有相同的鍵類型和值類型。
map<key, value> m(b,e);//創(chuàng)建map類型的對(duì)象m,存儲(chǔ)迭代器b和e標(biāo)記的范圍內(nèi)所有元素的副本,元素的類型必須能轉(zhuǎn)換為pair
//查
m.count(k);// 返回m中鍵值等于k的元素的個(gè)數(shù)。
m.find(k);// 如果m中存在按k索引的元素,則返回指向該元素的迭代器。如果不存在,則返回結(jié)束游標(biāo)end()。
//刪
//迭代器刪除
iter = m.find("123");
m.erase(iter);
//用關(guān)鍵字刪除
int n = m.erase("123"); //如果刪除了會(huì)返回1,否則返回0
//用迭代器范圍刪除 : 把整個(gè)map清空
m.erase(m.begin(), m.end());
//等同于m.clear()
m.erase(k); // 刪除m中鍵為k的元素,返回size_type類型的值,表示刪除元素的個(gè)數(shù)。
m.erase(p); // 從m中刪除迭代器p所指向的元素,p必須指向m中確實(shí)存在的元素,而且不能等于m.end(),返回void類型。
m.erase(iterator first, iterator last); // 刪除一個(gè)范圍,返回void類型。
//插入
// 第一種 用insert函數(shù)插入pair
m.insert(pair<int, string>(000, "student_zero"));
// 第二種 用insert函數(shù)插入value_type數(shù)據(jù)
m.insert(map<int, string>::value_type(001, "student_one"));
// 第三種 用"array"方式插入
m[123] = "student_first";
m[456] = "student_second";
m.insert(e) ;
e是一個(gè)用在m上的value_type類型的值。如果鍵e.first不在m中,則插入一個(gè)值為e.second的新元素;如果該鍵在m中已存在,那么不進(jìn)行任何操作。該函數(shù)返回一個(gè)pair類型對(duì)象,包含指向鍵為e.first的元素的map迭代器,以及一個(gè)bool類型的對(duì)象,表示是否插入了該元素。
m.insert(beg, end);
beg和end是標(biāo)記元素范圍的迭代器,對(duì)于該范圍內(nèi)的所有元素,如果它的鍵在m中不存在,則將該鍵及其關(guān)聯(lián)的值插入到m。 返回void類型。
m.insert(iter, e);
e是value_type類型的值,如果e.first不在m中,則創(chuàng)建新元素,并以迭代器iter為起點(diǎn)搜索新元素存儲(chǔ)的位置,返回一個(gè)迭代器,指向m中具有給定鍵的元素。 在添加新的map元素時(shí),使用insert成員可避免使用下標(biāo)操作符帶來(lái)的副作用:不必要的初始化。
//在往map里面插入了數(shù)據(jù),我們?cè)趺粗喇?dāng)前已經(jīng)插入了多少數(shù)據(jù)呢,可以用size函數(shù),用法如下:int nSize = mapStudent.size();
pair<map<int,string>::iterator,bool>Insert_Pair;
Insert_Pair=mapStudent.insert(map<int,string>::value_type(1, "student_one"));
我們通過(guò)pair的第二個(gè)變量來(lái)知道是否插入成功,它的第一個(gè)變量返回的是一個(gè)map的迭代器,如果插入成功的話Insert_Pair.second應(yīng)該是true的,否則為false。
4、使用示例
(1)插入
- insert 函數(shù)插入 pair 數(shù)據(jù)
std::map < int , std::string > mapPerson;
mapPerson.insert(pair < int,string > (1,"Jim"));
- insert 函數(shù)插入 value_type 數(shù)據(jù)
mapPerson.insert(std::map < int, std::string > ::value_type (2, "Tom"));
- 用數(shù)組方式插入數(shù)據(jù)
mapPerson[3] = "Jerry";
(2)遍歷
前向迭代器
std::map < int ,std::string > ::iterator it; std::map < int ,std::string > ::iterator itEnd; it = mapPerson.begin(); itEnd = mapPerson.end(); while (it != itEnd) { cout<<it->first<<' '<<it->second<<endl; it++; }
反向迭代器
std::map < int, string > ::reverse_iterator iter; for(iter = mapPerson.rbegin(); iter != mapPerson.rend(); iter++) cout<<iter->first<<" "<<iter->second<<endl;
數(shù)組形式
mapPerson.insert(std::map<int, std::string>::value_type (1, "Tom")); mapPerson[2] = "Jim"; mapPerson[3] = "Jerry"; int nSize = mapPerson.size(); for(int n = 1; n <= nSize; n++) qDebug()<<QString::fromStdString(mapPerson[n]);
(3)查找
三種數(shù)據(jù)查找方法
第一種:用count函數(shù)來(lái)判定關(guān)鍵字是否出現(xiàn),其缺點(diǎn)是無(wú)法定位數(shù)據(jù)出現(xiàn)位置,由于map的特性,一對(duì)一的映射關(guān)系,就決定了count函數(shù)的返回值只有兩個(gè),要么是0,要么是1,出現(xiàn)的情況,當(dāng)然是返回1了
第二種:用find函數(shù)來(lái)定位數(shù)據(jù)出現(xiàn)位置,它返回的一個(gè)迭代器,當(dāng)數(shù)據(jù)出現(xiàn)時(shí),它返回?cái)?shù)據(jù)所在位置的迭代器,如果map中沒(méi)有要查找的數(shù)據(jù),它返回的迭代器等于end函數(shù)返回的迭代器。
查找map中是否包含某個(gè)關(guān)鍵字條目用find()方法,傳入的參數(shù)是要查找的key,在這里需要提到的是begin()和end()兩個(gè)成員,
分別代表map對(duì)象中第一個(gè)條目和最后一個(gè)條目,這兩個(gè)數(shù)據(jù)的類型是iterator.
通過(guò)map對(duì)象的方法獲取的iterator數(shù)據(jù)類型是一個(gè)std::pair對(duì)象,包括兩個(gè)數(shù)據(jù) iterator->first和 iterator->second分別代表關(guān)鍵字和存儲(chǔ)的數(shù)據(jù)。
map<int ,string > ::iterator l_it;; l_it = maplive.find(112); if(l_it == maplive.end()) cout<<"we do not find 112"<<endl; else cout<<"wo find 112"<<endl;
第三種:這個(gè)方法用來(lái)判定數(shù)據(jù)是否出現(xiàn),是顯得笨了點(diǎn),
lower_bound函數(shù)用法,這個(gè)函數(shù)用來(lái)返回要查找關(guān)鍵字的下界(是一個(gè)迭代器)
upper_bound函數(shù)用法,這個(gè)函數(shù)用來(lái)返回要查找關(guān)鍵字的上界(是一個(gè)迭代器)
例如:map中已經(jīng)插入了1,2,3,4的話,如果lower_bound(2)的話,返回的2,
而upper-bound(2)的話,返回的就是3
Equal_range函數(shù)返回一個(gè)pair,pair里面第一個(gè)變量是Lower_bound返回的迭代器,pair里面第二個(gè)迭代器是Upper_bound返回的迭代器,如果這兩個(gè)迭代器相等的話,則說(shuō)明map中不出現(xiàn)這個(gè)關(guān)鍵字,
#include <map> #include <string> #include <iostream> using namespace std; int main() { map<int, string> mapStudent; mapStudent[1] = "student_one"; mapStudent[3] = "student_three"; mapStudent[5] = "student_five"; map<int, string>::iterator iter; iter = mapStudent.lower_bound(1); //返回的是下界1的迭代器 cout<<iter->second<<endl; iter = mapStudent.lower_bound(2); //返回的是下界3的迭代器 cout<<iter->second<<endl; iter = mapStudent.lower_bound(3); //返回的是下界3的迭代器 cout<<iter->second<<endl; iter = mapStudent.upper_bound(2); //返回的是上界3的迭代器 cout<<iter->second<<endl; iter = mapStudent.upper_bound(3); //返回的是上界5的迭代器 cout<<iter->second<<endl; pair<map<int, string>::iterator, map<int, string>::iterator> mappair; mappair = mapStudent.equal_range(2); if(mappair.first == mappair.second) cout<<"Do not Find"<<endl; else cout<<"Find"<<endl; mappair = mapStudent.equal_range(3); if(mappair.first == mappair.second) cout<<"Do not Find"<<endl; else cout<<"Find"<<endl; return 0; }
(4)刪除
iterator erase(iterator it) ;//通過(guò)一個(gè)條目對(duì)象刪除 iterator erase(iterator first,iterator last); //刪除一個(gè)范圍 size_type erase(const Key&key); //通過(guò)關(guān)鍵字刪除 clear();//就相當(dāng)于enumMap.erase(enumMap.begin(),enumMap.end());
到此這篇關(guān)于C++深入分析STL中map容器的使用的文章就介紹到這了,更多相關(guān)C++STL中map容器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++用指針變量作為函數(shù)的參數(shù)接受數(shù)組的值的問(wèn)題詳細(xì)總結(jié)
以下是對(duì)C++中用指針變量作為函數(shù)的參數(shù)接受數(shù)組的值的問(wèn)題進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助2013-10-10C++實(shí)現(xiàn)簡(jiǎn)單版通訊錄管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單版通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06C++如何實(shí)現(xiàn)定長(zhǎng)內(nèi)存池詳解
內(nèi)存池根據(jù)存儲(chǔ)的元素的長(zhǎng)度是否可變,分為變長(zhǎng),與定長(zhǎng)兩種內(nèi)存池,這篇文章主要給大家介紹了關(guān)于C++如何實(shí)現(xiàn)定長(zhǎng)內(nèi)存池的相關(guān)資料,需要的朋友可以參考下2021-09-09C語(yǔ)言深入回顧講解結(jié)構(gòu)體對(duì)齊
C 數(shù)組允許定義可存儲(chǔ)相同類型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類型,它允許你存儲(chǔ)不同類型的數(shù)據(jù)項(xiàng),本篇讓我們來(lái)了解C 的結(jié)構(gòu)體內(nèi)存對(duì)齊2022-06-06手把手教你實(shí)現(xiàn)一個(gè)C++單鏈表
鏈表是一種數(shù)據(jù)結(jié)構(gòu),用于數(shù)據(jù)的存儲(chǔ)。這篇文章主要為大家介紹了如何實(shí)現(xiàn)一個(gè)C++單鏈表,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下2022-11-11