1. 程式人生 > >C++基礎:C++標準庫之map簡介

C++基礎:C++標準庫之map簡介

1、綜述

        Map是C++STL中眾多的Container(容器)之一,與python的字典略類似,Map作為一個關聯容器,將key與value相互關聯,其中key為關鍵字,是不可更改的,而value是key值的相對應值。Map所提供的一對一的資料對映關係,在很多時候可以提供程式設計的極大便利。

        Map內部通過自建紅黑樹(一種非嚴格意義上的平衡二叉樹)實現,可以對資料自動排序,因而在map內部的所有資料是有序存放的。Map具有的一大特點是增加和刪除節點對迭代器的影響很小,除了那個操作節點,對其他的節點都沒有什麼影響。

Map具有如下的功能特點:

  • 自動建立Key - value的對應。key 和 value可以是任意你需要的型別。
  • 根據key值快速查詢記錄,查詢的複雜度基本是Log(N),如果有1000個記錄,最多查詢10次,1,000,000個記錄,最多查詢20次。
  • 快速插入Key - Value 記錄。
  • 快速刪除記錄
  • 根據Key 修改value記錄。
  • 遍歷所有記錄。

2、map的常見操作

(1)建構函式:

map<int,string> Mymap; 
map<int,string> Mymap2 (Mymap.begin(),Mymap.end());
map<int,string> Mymap3 (Mymap2); 
示例中int是key的型別,string是value的型別,可以為其他型別,如map<char,float> Mymap4; 


(2)插入資料:有幾種方式,下面舉三類例子。

Mymap[1] = "one"; //方式1
Mymap.insert(map<int,string>::value_type(11,"oneone"));//方式2
Mymap.insert(pair<int ,string>(111,"oneoneone"));//方式3
其中方式1簡單直觀,然而卻並不值得提倡,因其效能並不好。在插入key = 1的value=“one”時,需要首先在Mymap,查詢主鍵1是否已經存在,若不存在,則將一個新的物件插入Mymap,其key為1,但value是一個空字串,插入完成後,將value賦為"one"; 該方法會首先將每個值都賦為預設值,然後再賦為顯示的值,如果元素是類物件,則開銷比較大。而另外的方法則有效避免了這一問題。

(3)查詢元素:

利用find()方法,find()函式返回一個迭代器指向鍵值為key的元素,如果沒找到就返回指向map尾部的迭代器。

map<int ,string>::iterator itr;
itr = Mymap.find(1);
if(itr!=Mymap.end())//如找不到,返回Mymap.end()
{
	cout<<"找到key為1的項:"<<endl;
	cout<< itr->first <<" "<<itr->second<<endl;//可以列印該項的key和value
}
else
	cout<<"找不到key為1的項!"<<endl;

(4)刪除元素:

採用erase()方法實現:

	itr = Mymap.find(1);
	if(itr!=Mymap.end())
	{
		Mymap.erase(itr);//通過迭代器物件刪除
		//Mymap.erase(1);//也可以通過主鍵刪除
	}

erase()也可以刪除一個範圍如:
Mymap.erase(Mymap.begin(),Mymap.end());//相當於Mymap.clear(),可以清除整個map的內容

(5)swap()方法:

要注意的是,在map中swap()方法進行的是對於兩個map的交換,而非對map內兩個元素的交換。形如:

Mymap.swap(Mymap2);//交換兩個map

(6)size()方法:

返回map的大小,即元素的個數。

(7)empty()方法

判斷map是否為空,若map為空,則返回true。

(8)begin()方法:

返回指向map頭部的迭代器

(9)end()方法:

返回指向map尾部的迭代器

(10)count() 方法:

 返回指定元素出現的次數

3、常見操作程式例項

貼上一個簡單的程式集執行結果,以便於更好的理解。
//測試map用法
#include<map>
#include<string>
#include<iostream>
using namespace std;

void test_map()
{
	map<int ,string > Mymap;//key為int型,value為string型
	map<int ,string > Mymap2;
	pair<int ,string> Mypair;
	Mypair.first = 1;
	Mypair.second = "one";
	Mymap.insert(Mypair);//新增資料方式1
	Mymap.insert(map<int,string>::value_type(11,"oneone"));//新增資料方式二
	Mymap2[2] = "two"; //新增資料方法三,效率較差,不提倡
	Mymap2[22] = "twotwo";
	Mymap2.insert(pair<int ,string>(222,"twotwotwo"));
	map<int ,string>::iterator itr;//迭代器

	cout<<"Mymap中的內容為:"<<endl;
	for(itr = Mymap.begin();itr!=Mymap.end();itr++)//元素遍歷
	{
		cout<< itr->first <<" " << itr->second<<endl;
	}
	cout<<"Mymap2中的內容為:"<<endl;
	for(itr = Mymap2.begin();itr!=Mymap2.end();itr++)
	{
		cout<< itr->first <<" " << itr->second<<endl;
	}

	/////元素查詢
	itr = Mymap.find(11);//查詢map中某key對應的元素是否存在
	if(itr!=Mymap.end())//如找不到,返回Mymap.end()
	{
		cout<<"\n找到key為11的項:"<<endl;
		cout<< itr->first <<" "<<itr->second<<endl;
		itr->second = "oneoneone";
		cout<<"該項value修改為:"<<Mymap[11]<<endl;
	}
	
	Mymap.swap(Mymap2);//注意:交換的是兩個map
	cout<<"\n執行交換後:"<<endl;
	cout<<"Mymap中的內容為:"<<endl;
	for(itr = Mymap.begin();itr!=Mymap.end();itr++)
	{
		cout<< itr->first <<" " << itr->second<<endl;
	}
	cout<<"Mymap2中的內容為:"<<endl;
	for(itr = Mymap2.begin();itr!=Mymap2.end();itr++)
	{
		cout<< itr->first <<" " << itr->second<<endl;
	}

	cout<<"\n刪除Mymap2中key為1的項"<<endl;
	itr = Mymap2.find(1);
	if(itr!=Mymap2.end())
	{
		Mymap2.erase(itr);//
		//Mymap2.erase(1);//按key刪除,以上面的操作效果等效
	}
	cout<<"刪除後Mymap2中的內容為:"<<endl;
	for(itr = Mymap2.begin();itr!=Mymap2.end();itr++)
	{
		cout<< itr->first <<" " << itr->second<<endl;
	}
	if(!Mymap.empty())
	{
		cout<<"\nMymap大小為:"<<Mymap.size()<<endl;
		Mymap.clear();
		//Mymap.erase(Mymap.begin(),Mymap.end());//與clear()等效
		cout<<"clear()之後Mymap大小為:"<<Mymap.size()<<endl;
	}
}