程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++入門學習——標准模板庫之map

C++入門學習——標准模板庫之map

編輯:C++入門知識

C++入門學習——標准模板庫之map


map 是 STL 的一個關聯容器,它提供一對一(其中第一個可以稱為關鍵字,每個關鍵字只能在 map 中出現一次,第二個可能稱為該關鍵字的值)的數據處理能力,由於這個特性,它完成有可能在我們處理一對一數據的時候,在編程上提供快速通道。這裡簡單說一下 map 內部數據的組織,map內部自建一顆紅黑樹(一種非嚴格意義上的平衡二叉樹),這顆樹具有對數據自動排序的功能,所以在 map 內部所有的數據都是有序的,後邊我們會見識到有序的好處。

 

那什麼是一對一的數據映射?比如一個班級中,每個學生的學號跟他的姓名就存在著一一映射的關系,這個模型用 map 可能輕易描述,很明顯學號用 int 描述,姓名用字符串描述。

 

使用 map 之前,必須包含相應的頭文件,map 屬於 std 命名域的,因此需要通過命名限定:

#include

using std::map; //using namespace std;

 

 

1)map 的構造函數

map 共提供了 6 個構造函數,這塊涉及到內存分配器這些東西,略過不講,在下面我們將接觸到一些 map 的構造方法,我們通常用如下方法構造一個 map :

 

 

map mapStudent;

2) 數據的插入

 

在構造 map 容器後,我們就可以往裡面插入數據。這裡講三種插入數據的方法:

a)用 insert 函數插入 pair 數據:

 

#include 
#include	//map
#include  //string
#include  //pair

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//用insert函數插入pair數據
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用insert函數插入pair數據
	mapStudent.insert( pair(1, student_one) );
	mapStudent.insert( pair(2, student_two) );
	mapStudent.insert( pair(3, student_three) );
	
	//通過迭代器遍歷map的內容
	map::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
	    cout<first<< <second<

運行結果如下:

/

 

b)用 insert 函數插入 value_type 數據:

 

#include 
#include	//map pair
#include  //string
#include  //pair

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//用insert函數插入value_type數據
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用insert函數插入value_type數據
	mapStudent.insert( map::value_type(1, student_one) );
	mapStudent.insert( map::value_type(2, student_two) );
	mapStudent.insert( map::value_type(3, student_three) );
	
	//通過迭代器遍歷map的內容
	map::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
	    cout<first<< <second<
c)用數組方式插入數據:

 

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//用數組方式插入數據
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用數組方式插入數據
	mapStudent[0] = student_one;
	mapStudent[2] = student_two;
	mapStudent[3] = student_three;
	
	//通過迭代器遍歷map的內容
	map::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
	    cout<first<< <second<
運行結果如下:

 

/

以上三種用法,雖然都可以實現數據的插入,但是它們是有區別的。第一種和第二種在效果上是完成一樣的,用 insert 函數插入數據,在數據的插入上涉及到集合的唯一性這個概念,即當 map 中已經存在某個關鍵字時,insert 操作是不能成功插入數據,但是用數組方式則可以,它可以覆蓋以前該關鍵字對應的值。

 

那我們怎麼知道 insert 語句是否插入成功?我們可以用 pair 來獲得是否插入成功:

 

pair< map::iterator, bool > insert_pair;
insert_pair = mapStudent.insert( map::value_type(1, student_one) );

 

 

我們通過 pair 的第二個變量來判斷是否插入成功,它的第一個變量返回的是一個 map 的迭代器,如果插入成功的話 insert_pair.second 為 true,否則為 false。

 

完整測試代碼如下:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//測試插入是否成功
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	pair::iterator, bool> insert_pair;

	//插入數據
	insert_pair = mapStudent.insert(pair(1, student_one));
	if(insert_pair.second == true)//插入成功
	{
		cout << Insert Successfully << endl;
	}
	else
	{
		cout << Insert Failure << endl;
	}
	
	//插入數據
	insert_pair = mapStudent.insert(pair(1, student_two));
	if(insert_pair.second == true)//插入成功
	{
		cout << Insert Successfully << endl;
	}
	else
	{
		cout << Insert Failure << endl;
	}
	
	cout << 
------------------------
;
	//通過迭代器遍歷map的內容
	map::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
	    cout<first<< <second<
運行結果如下:

 

/

 

下面示例為測試數組賦值,數據覆蓋問題:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//測試數組賦值,數據覆蓋問題
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	mapStudent[1] = student_one;
	mapStudent[1] = student_two;	//這個也是 1
	mapStudent[2] = student_three;
	
	cout << 
------------------------
;
	//通過迭代器遍歷map的內容
	map::iterator iter;
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
	    cout<first<< <second<
運行結果如下:

 

/

 

3)map 的大小

在往 map 裡面插入了數據,我們怎麼知道當前已經插入了多少數據呢,可以用 size 函數,用法如下:

 

int nSize = mapStudent.size();

4)數據的遍歷

 

a)通過前向迭代器,上面舉例程序中就是使用此方式。


b)通過反相迭代器:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//使用反相迭代器遍歷map內容
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用insert函數插入pair數據
	mapStudent.insert( pair(1, student_one) );
	mapStudent.insert( pair(2, student_two) );
	mapStudent.insert( pair(3, student_three) );
	
	//cout << 
------------------------
;
	//使用反相迭代器遍歷map內容
	map::reverse_iterator iter;
	for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)
	{
	    cout<first<< <second<

 

 

運行結果如下:

/

 

c)通過數組方式:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//使用數組方式遍歷map內容
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用insert函數插入pair數據
	mapStudent.insert( pair(1, student_one) );
	mapStudent.insert( pair(2, student_two) );
	mapStudent.insert( pair(3, student_three) );
	
	//cout << 
------------------------
;
	//使用數組方式遍歷map內容
	int n = mapStudent.size();
	for(int i = 1; i <= n; i++) //從1開始
	{
	    cout<< i <<   << mapStudent[i]<

5)數據的查找

 

可以使用 find 函數來定位數據出現位置,它返回的一個迭代器,當數據出現時,它返回數據所在位置的迭代器,如果 map 中沒有要查找的數據,它返回的迭代器等於 end 函數返回的迭代器。示例代碼如下:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//用find函數來定位數據出現位置
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用insert函數插入pair數據
	mapStudent.insert( pair(1, student_one) );
	mapStudent.insert( pair(2, student_two) );
	mapStudent.insert( pair(3, student_three) );
	
	map::iterator iter;

	iter = mapStudent.find(1); //查找 1 的內容
	
	if( iter != mapStudent.end() ) //找到
	{
	    cout << Find, the value is: << iter->second << endl;
	
	}
	else
	{
	    cout << Do not Find << endl;
	}

	return 0;
}

運行結果如下:

 

/

 

 

6)數據的清空與判空

清空 map 中的數據可以用 clear() 函數,判定 map 中是否有數據可以用 empty() 函數,它返回 true 則說明是空 map。

 

 

 

7)數據的刪除

這裡要用到 erase 函數,它有三個重載了的函數,下面在例子中詳細說明它們的用法:

 

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

//數據的刪除
int main(int argc, char *argv[])
{
	
	map mapStudent;
	
	//用insert函數插入pair數據
	mapStudent.insert( pair(0, student_zero) );
	mapStudent.insert( pair(1, student_one) );
	mapStudent.insert( pair(2, student_two) );
	mapStudent.insert( pair(3, student_three) );
	mapStudent.insert( pair(4, student_four) );
	
	//如果要刪除1,用迭代器刪除
	map::iterator iter;
	iter = mapStudent.find(1); //先查找1
	mapStudent.erase(iter);
	
	cout << 
after erase 1:
;
	//通過迭代器遍歷map的內容
	for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
	    cout<first<< <second<first<< <second<first<< <second<
運行結果如下:

 

/

 

 

8)排序

這裡要講的是一點比較高深的用法:排序問題,STL 中默認是采用小於號來排序的,以上代碼在排序上是不存在任何問題的,因為上面的關鍵字是 int 型,它本身支持小於號運算,在一些特殊情況,比如關鍵字是一個結構體,涉及到排序就會出現問題,因為它沒有小於號操作,insert 等函數在編譯的時候過不去,測試代碼如下:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

typedef struct tagStudentInfo
{
	int nID;
	string strName;
}StudentInfo, *PStudentInfo; //學生信息

//數據的刪除
int main(int argc, char *argv[])
{
	
	//用學生信息映射分數
	map mapStudent;

	StudentInfo studentInfo;
	studentInfo.nID = 1;
	studentInfo.strName = student_one;
	mapStudent.insert( pair(studentInfo, 90) );

	studentInfo.nID = 2;
	studentInfo.strName = student_two;
	mapStudent.insert( pair(studentInfo, 80) );

 
	map::iterator iter;
	for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
		cout<first.nID<< <first.strName<< <second<

 

以上程序是無法編譯通過的

解決方法為:重載小於號。示例如下:

 

#include 
#include	//map pair
#include  //string

using std::endl;
using std::cin;
using std::cout;
using std::map;
using std::string;
using std::pair;
//using namespace std;//或直接把所有都包含

typedef struct tagStudentInfo
{
	int nID;
	string strName;
	
	bool operator< (tagStudentInfo const &temp) const
	{
		//這個函數指定排序策略,按nID排序,如果nID相等的話,按strName排序
		if(nID < temp.nID)  return true;
		
		if(nID == temp.nID) return strName.compare(temp.strName);
		
		return false;
	}
	
}StudentInfo, *PStudentInfo; //學生信息

//數據的刪除
int main(int argc, char *argv[])
{
	
	//用學生信息映射分數
	map mapStudent;

	StudentInfo studentInfo;
	studentInfo.nID = 1;
	studentInfo.strName = student_one;
	mapStudent.insert( pair(studentInfo, 90) );

	studentInfo.nID = 2;
	studentInfo.strName = student_two;
	mapStudent.insert( pair(studentInfo, 80) );

 
	map::iterator iter;
	for (iter = mapStudent.begin(); iter != mapStudent.end(); iter++)
	{
		cout<first.nID<< <first.strName<< <second<

 

運行結果圖如下:

 

/

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved