C++關聯容器之map


1.map簡介

  map中的元素是關鍵字-值對:關鍵字起到索引的作用,值表示與索引相關的數據。我們常用的字典就是很好的map的實例,單詞作為索引,其中文含義代表其值。map類型通常被稱為關聯數組,其和數組很相似,只不過其下標不是整數而是關鍵

,我們通過關鍵字來查找值而不是位置。比如電話簿也是一個map的例子,姓名作為關鍵字其對應的值就為該人的電話號碼。map類型定義在頭文件map中

注意:map是有序的且不允許重復關鍵字的關聯容器!其有序的實現是依靠關鍵字類型中的"<"來實現的。

 

2.map的定義與初始化

  2.1 創建空map

map<key_type,value_type> tempMap;//創建空map

  2.2 列表初始化map

map<key_type,value_type> tempMap{
  {key1,value1},
  {key2,value2},
  ......};

  2.3 使用已有的map復制構造

map<key_type,value_type> tempMap(existMap);//注意關鍵字類型與值類型匹配

   2.4  指定已有map的迭代器返回進行構造

map<key_type,value_type> tempMap(b,e);//b,e為已有map對象的迭代器范圍

 

3.map的賦值操作

  我們可以將一個已有的map賦值給另一個map:

map1=map2;

map也支持列表賦值:

map<key_type,value_type> tempMap={   {key1,value1},   {key2,value2},   ......};

 

4.關聯容器額外的類型別名

  除了之前的容器操作具有的類型,map有自己獨特的類型別名:

類型別名

說明

key_type

關鍵字類型

 mapped_type

關鍵字關聯的類型

 value_type

pair<const key_type,mapped_type>

舉例

map<int ,string> myMap; myMap::value_type v1;//v1為pair<const int ,string>類型
myMap::key_type v2;//v2為int類型
myMap::mapped_type v3;//v3為string類型

 

5. 新的數據類型  pair類型

  pair標准類型定義在頭文件utility中,一個pair保存兩個數據成員,pair是用來生成特定類型的模板,當創建一個pair對象時必須要提供兩個類型名

pair<string string> A;//保存兩個string
pair<string ,size_t> B;//保存一個string,一個size_t
pair<int ,vector<int>> C;//保存一個int和vector<int>

上面的代碼都是執行了默認構造函數來對數據成員進行初始化,我們也可以初始化器:

pair<string,string> thePair{"Hello","World"};

pair的數據成員是public的,並且成員命名為first和second,我們可以使用普通的成員訪問符“.”來進行訪問。

  我們可以在pair上的操作如下:

操作 

說明

pair<T1,T2> P;

p的成員數據類型分別為T1,T2,並執行默認初始化

pair<T1,T2> p(v1,v2);

P的成員數據類型分別為T1,T2,並且使用v1,v2分別初始化

pair<T1,T2> p={v1,v2};

等價於上式

make_pair(v1,v2);

返回一個v1和v2初始化的pair,其類型由v1和v2推斷而來

p.first

返回p的first成員

 p.second

返回p的second成員

 p1 relop p2

執行關系運算(>,<,<=,>=),利用數據類型中的關系運算

 p1==p2

相等性判斷,必須first和second同時滿足要求

p1!=p2 

不等於判斷

 

5.1 創建使用pair對象的函數

pair<int ,string> do_something(vecotr<string> &v) { if(!v.empty()) { return {v.back().size(),v.back()}; } else { return pair<int ,string>(); } }

有些較早版本的編譯器不支持花括號返回,那我們可以先構造pair對象再返回

pair<int ,string> do_something(vecotr<string> &v) { if(!v.empty()) { return pair<int ,string>(v.back().size(),v.back());//也可使用make_pair來生成pair對象
   }
else { return pair<int ,string>(); } }

 

6.map的迭代器

  當我們對map的迭代器進行解引用的時候我們得到的是value_type類型,也就是一個pair類型,要注意的是其first成員是const的,second成員是非常量成員,很明顯我們不能改變map關鍵字,但我們可以改變關鍵字所關聯的值,我們可以使用迭代器來遍歷我們的map對象

auto map_iter=myMap.cbegin(); while(map_iter!=myMap.cend()) { cout<<"key: "<<map_iter->first<<"value: "<<map_iter->second<<endl; ++map_iter; } 

  注意:由於map中的關鍵字是const,我們一般不對map使用泛型算法!

 

7.向map添加元素

  我們使用insert對map進行元素添加操作,我們必須要記住的一點就是map的元素是pair類型的,下面列舉常用的insert方法:

myMap.insert({k1,v1}); myMap.insert(make_pair(k2,v2)); myMap.insert(pair<key_type,value_type>(k3,v3)); myMap.insert(map<key_type,value_type>::value_type(k4,v4));

下面列舉其他的一些添加元素的方式:

操作

說明

c.insert(v)

v為value_type對象,返回一個pair包含一個迭代器和是否成功插入的bool值,關鍵詞不存在才插入

c.emplace(args)

args用來構造元素,返回一個pair包含一個迭代器和是否成功插入的bool值,關鍵詞不在才插入

c.insert(b,e)

b和e是迭代器,指定多個元素插入,返回void

c.insert(il)  

il花括號列表形式,返回void

c.insert(p.v)

和insert(v)類似,p是迭代器,指定從哪里開始搜索新元素應該存儲的位置,返回值為一個迭代器,指出具有給定關鍵字的元素

c.emplace(p,args)

和c.emplace(args)類似,p是迭代器,指定從哪里開始搜索新元素應該存儲的位置,返回值為一個迭代器,指出具有給定關鍵字的元素

 7.1 檢測insert的返回值

   添加單一元素的insert和emplace返回值一個pair,告訴我們插入是否成功,pair的first是一個迭代器,指向具有給定關鍵字的元素,second是一個bool型,如果插入成功為true,否則為false。如果關鍵字已經在map中那么insert和emplace什么也不做。

 

8.刪除元素

  使用erase函數來執行map的刪除操作:

操作

說明

c.erase(k)

刪除c中關鍵詞為k的元素,返回值為size_type類型,指出刪除元素的數目,因為map中不允許重復,返回值為0或者1

c.erase(p)

從c中刪除迭代器p指定的元素,p必須指向一個真實存在的元素,返回值指向p之后元素的迭代器,如果p指向c的微元素,那么將返回c.end()

 c.erase(b,e)

刪除迭代器對b和e所表示返回的元素,返回值迭代器e 

 

9. map的下標操作

  map提供了下標操作和at函數操作。我們對map使用下標操作要注意下標是關鍵字,還要注意的是對不存在map中的關鍵字使用了下標操作,會添加一個具有該關鍵字的元素到map中。

操作

說明

c[k]

返回關鍵字為k的元素,如果k不在c中,添加一個關鍵字為k的元素,對其進行初始化

c.at(k)

訪問關鍵字為k的元素,帶參數檢查,如果k不在c中,則返回out_of_range異常

9.1使用下標操作的返回值

   當我們對一個map進行下標操作的時候,會獲得mapped_type對象,但當解引用map的迭代器時,會得到一個value_type對象,如果關鍵字不存在map中,下標運算依然會添加一個具有該關鍵字的新元素。在我們不確定一個元素是否在map中,且不想在map中進行添加就不能使用下標操作。

 

10.訪問元素

  當我們要確定一個元素是否存在map中,使用find是最佳的選擇,對於不允許重復關鍵字的map來說,使用count函數返回的關鍵字計數只能為0和1。對於map元素的訪問還有如下的操作:

操作  

說明

c.find(k)

返回一個迭代器,指向第一個關鍵字為k的元素,如果不在map中,則返回尾后迭代器c.end()

c.count(k)

返回關鍵字等於k的元素數量,對於map返回值只能為0和1

c.lower_bound(k)

返回一個迭代器,指向第一個關鍵字不小於k的元素

c.upper_bound(k)

返回一個迭代器,指向第一個關鍵字大於k的元素

c.equal_range(k)

返回一個迭代器pair,表示關鍵字等於k元素的范圍,如果k不存在,則pair的數據成員全是c.end()

備注:如果使用lower_bound和upper_bound匹配關鍵字k,返回了相同的迭代器,那么關鍵字k不在map中。

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM