STL快速入門學習教程之map的簡單使用
map是STL中的一個關聯容器,它以一對一的數據進行整理(第一個數值稱爲關鍵字,且這個關鍵字只能在map中出現一次,第二個數值稱爲前關鍵字的值),正是由於這種特性,我們可以使用map處理一對一數據的時候的到快速的處理方式。map具有自動排序的功能,在map中的數據都是有序的。
1.map介紹
map是一個關聯式的容器,它的特點是增加和刪除節點時對迭代器的影響很小,除了操作的節點,對其他節點都不會產生什麼影響,對於map容器來說,不能修改其key值,但key所對應的值可以修改。
2.map的性質
1.自動建立key與value的對應關係
2.key與value可以是你需要的任意數據類型(如:簡單數據類型或者複合數據類型)
3.使用insert進行快速的插入Key和value的值
4.根據key的值進行快速的查找記錄,查找的時間複雜度爲log(N)
5.能進行快速的刪除記錄
6.根據key的值快速的修改value的值
7.和其他容器一樣能遍歷所有記錄
3.使用原則
使用頭文件#include< map>才能使用map類
map對象是模板類,需要使用關鍵字和存儲對象兩個模板參數:
map< int,string> number;
這樣便定義了一個用int作爲索引,並且擁有關聯指向string的指針
4.構造函數
map共提供了6個構造函數,這塊涉及到內存分配器這些東西,略過不表,在下面我們將接觸到一些map的構造方法,這裏要說下的就是,我們通常用如下方法構造一個map:
map< int,string> mapstu;
5.數據的插入
三種插入數據的方法:
第一種:用insert函數插入pair數據
第二種:用insert函數插入value_type數據
第三種:用數組的方式插入數據
1.用insert函數插入pair數據
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map()
{
map<int,string> stu;
stu.insert(pair<int, string>(1001, "李華"));
stu.insert(pair<int, string>(1002, "李明"));
stu.insert(pair<int, string>(1003, "李強"));
stu.insert(pair<int, string>(1004, "李平"));
stu.insert(pair<int, string>(1005, "李雨"));
for (map<int, string>::iterator it = stu.begin();it != stu.end();it++)
{
cout << it->first<<" "<<it->second << endl;
}
}
int main()
{
init_map();
system("pause");
return 0;
}
運行結果:
2.用insert函數插入value_type數據
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map(map<int,string> &ma)
{
map<int, string>::iterator it;
for (it = ma.begin();it != ma.end();it++)
{
cout << it->first << " " <<it->second<< endl;
}
}
int main()
{
map<int, string> stu;
stu.insert(map<int, string>::value_type(1001, "李明"));
stu.insert(map<int, string>::value_type(1002, "王明"));
stu.insert(map<int, string>::value_type(1003, "張明"));
stu.insert(map<int, string>::value_type(1004, "韋明"));
stu.insert(map<int, string>::value_type(1005, "莫明"));
init_map(stu);
system("pause");
return 0;
}
運行結果:
3.用數組的方式插入數據
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map(map<int, string> &ma)
{
map<int, string>::iterator it;
for (it = ma.begin();it != ma.end();it++)
{
cout << it->first << " " << it->second << endl;
}
}
int main()
{
map<int, string> stu;
stu[0] = { "曉華" };
stu[1] = { "曉花" };
stu[2] = { "曉強" };
stu[3] = { "曉平" };
stu[4] = { "曉明" };
init_map(stu);
system("pause");
return 0;
}
運行結果:由結果可知,key值能夠自動增加
雖然以上方式都能插入數據,但是它們的實現方法是有區別的,前二者方式基本一致,都使用insert函數進行數據的插入,但是特殊之處在於,插入數據時檢測key值的唯一性,即當map中含有相應的key值時是無法插入數據的,但是數組插入的方式就不一樣,它可以覆蓋以前該關鍵字對應的值,無圖無真相:
pair<map<int, string>::iterator, bool>pair_if; //用pair來獲取24行是否插入成功
map<int, string> stu;
pair_if=stu.insert(map<int, string>::value_type(1001, "李明"));
數組插入的方式直接覆蓋:
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map(map<int, string> &ma)
{
map<int, string>::iterator it;
for (it = ma.begin();it != ma.end();it++)
{
cout << it->first << " " << it->second << endl;
}
}
int main()
{
map<int, string> stu;
stu[0] = { "曉華" };
stu[1] = { "曉花" };
stu[2] = { "曉強" };
stu[3] = { "曉平" };
stu[4] = { "曉明" };
stu[0] = { "曉雨" };
init_map(stu);
system("pause");
return 0;
}
運行結果:
6.map的大小
map的元素個數:
int map_size=stu.size();
修改的main函數:
int main()
{
map<int, string> stu;
stu[0] = { "曉華" };
stu[1] = { "曉花" };
stu[2] = { "曉強" };
stu[3] = { "曉平" };
stu[4] = { "曉明" };
stu[5] = { "曉雨" };
int map_size = stu.size();
init_map(stu);
cout << "map的元素個數爲:" << map_size << endl;
system("pause");
return 0;
}
結果:
7.數據的遍歷
使用迭代器:
1.向前迭代器。其實前面我們使用的方式都是該種方式進行數據的遍歷輸出。
2.反向迭代器。具體看下面的代碼操作:
修改如下:
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map()
{
map<int,string> stu;
stu.insert(pair<int, string>(1001, "李華"));
stu.insert(pair<int, string>(1002, "李明"));
stu.insert(pair<int, string>(1003, "李強"));
stu.insert(pair<int, string>(1004, "李平"));
stu.insert(pair<int, string>(1005, "李雨"));
cout << "前向迭代器的輸出結果如下:" << endl;
for (map<int, string>::iterator it = stu.begin();it != stu.end();it++)
{
cout << it->first<<" "<<it->second << endl;
}
cout << endl;
cout << "反向迭代器的輸出結果如下:" << endl;
for (map<int, string>::reverse_iterator lit = stu.rbegin();lit != stu.rend();lit++)
{
cout << lit->first << " " << lit->second << endl;
}
}
int main()
{
init_map();
system("pause");
return 0;
}
輸出區別:
使用數組進行輸出:
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map(map<int, string> &ma)
{
map<int, string>::iterator it;
for (it = ma.begin();it != ma.end();it++)
{
cout << it->first << " " << it->second << endl;
}
}
int main()
{
map<int, string> stu;
stu[0] = { "曉華" };
stu[1] = { "曉花" };
stu[2] = { "曉強" };
stu[3] = { "曉平" };
stu[4] = { "曉明" };
stu[5] = { "曉雨" };
int map_size = stu.size();
cout << "使用迭代器輸出內容:" << endl;
init_map(stu);
cout << "map的元素個數爲:" << map_size << endl;
cout << endl;
cout << "使用數組進行map元素的輸出:" << endl;
for (int i = 0;i < map_size;i++)
{
cout << stu[i] << endl;
}
system("pause");
return 0;
}
結果:
數組反向遍歷這裏不再給出,同樣使用數組下標索引值進行反向遍歷即可。
8.判斷map中的元素
在這裏我們將體會,map在數據插入時保證有序的好處。
要判定一個數據(關鍵字)是否在map中出現的方法比較多,這裏標題雖然是數據的查找,在這裏將穿插着大量的map基本用法。
這裏給出三種數據查找方法:
第一種:用count函數來判定關鍵字是否出現,其缺點是無法定位數據出現位置,由於map的特性,一對一的映射關係,就決定了count函數的返回值只有兩個,要麼是0,要麼是1,出現的情況,當然是返回1了
第二種:用find函數來定位數據出現位置,它返回的一個迭代器,當數據出現時,它返回數據所在位置的迭代器,如果map中沒有要查找的數據,它返回的迭代器等於end函數返回的迭代器。
查找map中是否包含某個關鍵字條目用find()方法,傳入的參數是要查找的key,在這裏需要提到的是begin()和end()兩個成員,
分別代表map對象中第一個條目和最後一個條目,這兩個數據的類型是iterator.
程序:
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map()
{
map<int,string> stu;
stu.insert(pair<int, string>(1001, "李華"));
stu.insert(pair<int, string>(1002, "李明"));
stu.insert(pair<int, string>(1003, "李強"));
stu.insert(pair<int, string>(1004, "李平"));
stu.insert(pair<int, string>(1005, "李雨"));
//cout << "前向迭代器的輸出結果如下:" << endl;
//for (map<int, string>::iterator it = stu.begin();it != stu.end();it++)
//{
// cout << it->first<<" "<<it->second << endl;
//}
//cout << endl;
//cout << "反向迭代器的輸出結果如下:" << endl;
//for (map<int, string>::reverse_iterator lit = stu.rbegin();lit != stu.rend();lit++)
//{
// cout << lit->first << " " << lit->second << endl;
//}
map<int, string>::iterator iter;
iter = stu.find(1001);
if (iter != stu.end())
{
cout << "Find, the value is " << iter->second << endl;
}
else
{
cout << "Do not Find" << endl;
}
}
int main()
{
init_map();
system("pause");
return 0;
}
結果:
第三種方法:
lower_bound函數,這個函數用來返回要查找關鍵字的下界(是一個迭代器)
upper_bound函數,這個函數用來返回要查找關鍵字的上界(是一個迭代器)
例如:map中已經插入了1001,1002,1003,1004的話,如果lower_bound(1002)的話,返回的1002,而upper-bound(1002)的話,返回的就是1003
Equal_range函數返回一個pair,pair裏面第一個變量是Lower_bound返回的迭代器,pair裏面第二個迭代器是Upper_bound返回的迭代器,如果這兩個迭代器相等的話,則說明map中不出現這個關鍵字,
程序:
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map(map<int, string> &ma)
{
map<int, string>::iterator it;
for (it = ma.begin();it != ma.end();it++)
{
cout << it->first << " " << it->second << endl;
}
}
int main()
{
map<int, string> stu;
//stu[0] = { "曉華" };
stu[1] = { "曉花" };
//stu[2] = { "曉強" };
stu[3] = { "曉平" };
//stu[4] = { "曉明" };
stu[5] = { "曉雨" };
int map_size = stu.size();
//cout << "使用迭代器輸出內容:" << endl;
//init_map(stu);
//cout << "map的元素個數爲:" << map_size << endl;
//cout << endl;
//cout << "使用數組進行map元素的輸出:" << endl;
//for (int i = 0;i < map_size;i++)
//{
// cout << stu[i] << endl;
//}
map<int, string>::iterator iter;
iter = stu.lower_bound(1); //返回的是下界1的迭代器
cout << iter->second << endl;
iter = stu.lower_bound(2); //返回的是下界3的迭代器
cout << iter->second << endl;
iter = stu.lower_bound(3); //返回的是下界3的迭代器
cout << iter->second << endl;
iter = stu.upper_bound(2); //返回的是上界3的迭代器
cout << iter->second << endl;
iter = stu.upper_bound(3); //返回的是上界5的迭代器
cout << iter->second << endl;
pair<map<int, string>::iterator, map<int, string>::iterator> mappair;
mappair = stu.equal_range(2);
if (mappair.first == mappair.second)
cout << "找不到" << endl;
else
cout << "找到了" << endl;
mappair = stu.equal_range(3);
if (mappair.first == mappair.second)
cout << "找不到" << endl;
else
cout << "找到了" << endl;
system("pause");
return 0;
}
結果:
9.從map中刪除元素
移除某個map中某個條目用erase()
該成員方法的定義如下:
iterator erase(iterator it);//通過一個條目對象刪除
iterator erase(iterator first,iterator last)//刪除一個範圍
size_type erase(const Key&key);//通過關鍵字刪除
clear()就相當於enumMap.erase(enumMap.begin(),enumMap.end());
下面要用到erase函數,它有三個重載了的函數,下面在例子中詳細說明它們的用法:
#include <iostream>
#include <map>
#include <string>
using namespace std;
void init_map()
{
map<int,string> stu;
stu.insert(pair<int, string>(1001, "李華"));
stu.insert(pair<int, string>(1002, "李明"));
stu.insert(pair<int, string>(1003, "李強"));
stu.insert(pair<int, string>(1004, "李平"));
stu.insert(pair<int, string>(1005, "李雨"));
//使用迭代器刪除
map<int, string>::iterator iter;
iter = stu.find(1001);
stu.erase(iter);
//使用關鍵字刪除
int n = stu.erase(1002);
for (map<int, string>::iterator it = stu.begin();it != stu.end();it++)
{
cout << it->first << " " << it->second << endl;
}
cout << "下面將會清空map" << endl;
//用迭代器,成片的刪除
//如下代碼將map清空
stu.erase(stu.begin(), stu.end());
//cout << "前向迭代器的輸出結果如下:" << endl;
for (map<int, string>::iterator it = stu.begin();it != stu.end();it++)
{
cout << it->first<<" "<<it->second << endl;
}
cout << endl;
//cout << "反向迭代器的輸出結果如下:" << endl;
//for (map<int, string>::reverse_iterator lit = stu.rbegin();lit != stu.rend();lit++)
//{
// cout << lit->first << " " << lit->second << endl;
//}
//map<int, string>::iterator iter;
//iter = stu.find(1001);
//if (iter != stu.end())
//{
// cout << "Find, the value is " << iter->second << endl;
//}
//else
//{
// cout << "Do not Find" << endl;
//}
}
int main()
{
init_map();
system("pause");
return 0;
}
結果:
10.map的基本操作函數
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的函數