C++STL之map映照容器
阿新 • • 發佈:2019-01-26
clu 排序 遍歷map 直接 bsp int 多重 1.4 位置 map映照容器
map映照容器的元素數據是由一個鍵值和一個映照數據組成的, 鍵值與映照數據之間具有一一映照關系.
map映照容器的數據結構也是采用紅黑樹來實現的, 插入元素的鍵值不允許重復, 比較函數只對元素的鍵值進行比較, 元素的各項數據可通過鍵值檢索出來. 由於map與set采用的都是紅黑樹的數據結構, 所以, 用法基本相似.
鍵值 映照數據
Name Score
Jack 98.5
Bomi 96.0
Kate 97.5
使用map容器需要包含頭文件"#include<map>", map文件包含了對multimap多重映照容器的定義.
1.1map創建, 插入元素和遍歷訪問
創建map對象, 鍵值與映照數據的類型由自己去定義. 在沒有指定比較函數時, 元素的插入位置是按鍵值由小到大到紅黑樹中去的, 這點和set一樣. 下面這個程序詳細的說明了如何操作map容器.
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
//定義map對象, 當前沒有任何元素
map<string, float> m;
//插入元素, 按鍵值的由小到大放入紅黑樹中
m["Jack"] = 98.5;
m["Bomi"] = 96.0;
m["Kate"] = 97.5;
//向前遍歷元素
map<string, float>::iterator it;
for(it = m.begin(); it != m.end(); it++)
{
//輸出鍵值與映照數據
cout << (*it).first << " : " << (*it).second << endl;
}
return 0;
}
/*
Bomi : 96
Jack : 98.5
Kate : 97.5
*/
1.2刪除元素
與set容器一樣, map映照容器的erase()刪除元素函數, 可以刪除某個叠代器位置上的元素, 等於某個鍵值的元素, 一個叠代器區間上的所有元素, 當然, 也可以使用clear()方法清空map映照容器.
下面這個程序演示了刪除map容器中鍵值為28的元素:
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
//定義map對象, 當前沒有任何元素
map<int , char> m;
//插入元素, 按鍵值的由小到大放入紅黑樹中
m[25] = ‘m‘;
m[28] = ‘k‘;
m[10] = ‘x‘;
m[30] = ‘a‘;
//刪除值為28的元素
m.erase(28);
//前向遍歷元素
map<int, char>::iterator it;
for(it = m.begin(); it != m.end(); it++)
{
//輸出鍵值與映照數據
cout << (*it).first << " : " << (*it).second << endl;
}
return 0;
}
/*
10 : x
25 : m
30 : a
*/
1.3元素反向遍歷
可以使用反向叠代器reverse_iterator反向遍歷map映照容器中的數據, 它需要rbegin()方法和rend()方法指出反向遍歷的起始位置和終止位置.
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
//定義map對象, 當前沒有任何元素
map<int,char> m;
//插入元素, 按鍵值的由小到大放入紅黑樹中
m[25] = ‘m‘;
m[28] = ‘k‘;
m[10] = ‘x‘;
m[30] = ‘a‘;
//反向遍歷元素
map<int, char>::reverse_iterator rit;
for(rit = m.rbegin(); rit != m.rend(); rit++)
{
//輸出鍵值與映照數據
cout << (*rit).first << " : " << (*rit).second << endl;
}
return 0;
}
/*
30 : a
28 : k
25 : m
10 : x
*/
1.4元素的搜索
使用find()方法來搜索某個鍵值, 如果搜索到了, 則返回該鍵值所在的叠代器位置, 否則, 返回end()叠代器位置. 由於map采用紅黑樹數據結構來實現, 所以搜索速度是極快的.
下面這個程序搜索鍵值為28的元素:
#include<map>
#include<string>
#include<iostream>
using namespace std;
int main()
{
map<int, char> m;
//插入元素, 按鍵值的由小到大順序放入紅黑樹中
m[25] = ‘m‘;
m[28] = ‘k‘;
m[10] = ‘x‘;
m[30] = ‘a‘;
map<int, char>::iterator it;
it = m.find(28);
if(it != m.end())
{
cout << (*it).first << " : " << (*it).second << endl;
}
else
{
cout << "not found it" << endl;
}
return 0;
}
/*
28 : k
*/
1.5自定義比較函數
將元素插入到map中去的時候, map會根據設定的比較函數將該元素放到該放的節點上去. 在定義map的時候, 如果沒有指定比較函數, 那麽采用默認的比較函數, 即按鍵值由小到大的順序插入元素. 在很多情況下, 需要自己編寫比較函數.
編寫比較函數與set比較函數是一致的, 因為它們的內部數據結構都是紅黑樹. 編寫方法有兩種:
(1)如果元素不是結構體, 那麽, 可以編寫比較函數規則是要求按鍵值由大到小的順序將元素插入到map中:
#include<map>
#include<string>
#include<iostream>
using namespace std;
//自定義比較函數myComp
struct myComp
{
bool operator() (const int &a, const int &b)
{
if(a != b) return a > b;
else return a > b;
}
};
int main()
{
//定義map對象, 當前沒有任何元素
map<int, char, myComp> m;
//插入元素, 按鍵值的由小到大放入紅黑樹中
m[25] = ‘m‘;
m[28] = ‘k‘;
m[10] = ‘x‘;
m[30] = ‘a‘;
//使用前向叠代器中序遍歷map
map<int, char, myComp>::iterator it;
for(it = m.begin(); it != m.end(); it++)
{
cout << (*it).first << " : " << (*it).second << endl;
}
return 0;
}
/*
30 : a
28 : k
25 : m
10 : x
*/
(2)如果元素是結構體, 那麽, 可以直接把比較函數寫在結構體內. 下面的程序詳細說明了如何操作:
#include<map>
#include<string>
#include<iostream>
using namespace std;
struct Info
{
string name;
float score;
//重載"<"操作符, 自定義排序規則
bool operator < (const Info &a) const
{
//按score由大到小排列. 如果要由小到大排列, 使用">"號即可
return a.score < score;
}
};
int main()
{
//定義map對象, 當前沒有任何元素
map<Info, int> m;
//定義Info結構體變量
Info info;
//插入元素, 按鍵值的由小到大放入紅黑樹中
info.name = "Jack";
info.score = 60;
m[info] = 25;
info.name = "Bomi";
info.score = 80;
m[info] = 10;
info.name = "Peti";
info.score = 66.5;
m[info] = 30;
//使用前向叠代器中序遍歷map
map<Info, int>::iterator it;
for(it = m.begin(); it != m.end(); it++)
{
cout << (*it).second << " : ";
cout << ((*it).first).name << " " << ((*it).first).score << endl;
}
return 0;
}
/*
10 : Bomi 80
30 : Peti 66.5
25 : Jack 60
*/
P51
C++STL之map映照容器