map是一個關聯式容器,map和set封裝了二叉樹支持高效的關鍵字查找和訪問,map中的的元素是關鍵字-值(key-value)對,關鍵字是起索引作用,根據關鍵字查找關鍵字所對應的值。Map細分爲不允許重複有序元素map,允許重複有序元素multimap,不允許重複無序元素unordered_map,允許重複無序元素unordered_multimap四種map,前2個在map頭文件中,後2個在unordered_map中。
template < class Key, //map::key_tpe
class T, //map::mapped_type
class Compare = less<Key>, //map::key_compare
class Alloc = allocator<pair<const Key, T>> //map::allocator_type
> class map;
map的創建:
map<string,int> mymap;
當map中要包含我們的自定義類型時,必須在自定義類型中重載比較函數或者在外部寫一個比較函數。比如我們自定類型爲:
struct People{
int age;
int height;
bool operator<(const People &b) const{
return age<b.age;
}
};
bool compare(const People &a,const People &b){
return a.age<b.age;
}
map<People,int> mymap; //重載<
map<People,int, decltype(&compare)> mymap(compare); //外部寫比較函數
講map時,還要講一下pair,pair是一種模板類型,在頭文件utility中,一個pair保存2個數據成員,數據成員是public的。
pair<T1,T2> p
pair<T1,T2> p(v1,v2)
pair<T1,T2> p={v1,v2}
make_pair(v1,v2)
p.first() //返回名爲first的數據成員
p.second() //返回名爲second的數據成員
map中每一個元素是一個pair對象,所以他的value_type爲pair類型,當我們使用map的迭代器,並對其解引用時,得到的就是一個pair,注意map的關鍵字是不能改變的,是一個const的關鍵字,只能改變map的值。
map<string,string>::iterator iter=p.begin()
auto iter=p.begin()
map的常用操作:
map<string,int> p
p.insert({"word",1}) //插入元素
p.insert(make_pair("word",1))
p.insert(pair<string,int>("word",1))
p.insert(map<string,int>::value_type("word",1))
auto ret=p.insert(make_pair("word",1)) // 對於不包含重複關鍵字的map,insert操作返回一個
pair元素,即ret是一個pair,ret的第一個元素ret.first()是一個迭代器,指向具有給定關鍵字的元素,
第二個元素ret.second()是一個bool類型,表示當前插入是否成功,不成功返回false,說明當前
元素已經存在。
p.erase(k) 刪除每個關鍵字值爲k的元素,返回刪除元素的個數
p.erase(iter) 刪除每迭代器iter指向的元素,返回指向iter之後元素的迭代器,若iter指向尾元素,
返回p.end()
p.erase(b,e) 刪除迭代器b,e之間的所有元素,返回e
//map和unordered_map的下標操作
p[k] 返回關鍵字爲k的元素,若不存在則會添加關鍵字爲k的元素,並對其進行值初始化
p.at(k) 訪問關鍵字爲k的元素,若不存在拋出out_of_range異常
p.find(k) 返回一個迭代器,指向第一個關鍵字值爲k的元素,若不存在返回尾迭代器
p.count(k) 返回關鍵字等於k的元素的數量,不存在返回0
set和map類似,只不過只能存儲一個元素或對象並且一個鍵值在set只可能出現0或1次,map存儲的是一對元素或對象,鍵值可以出現多次。它們的函數基本相同
set<int> myset;
begin() ,返回set容器的第一個元素
end() ,返回set容器的最後一個元素
clear() ,刪除set容器中的所有的元素
empty() ,判斷set容器是否爲空
max_size() ,返回set容器可能包含的元素最大個數
size() ,返回當前set容器中的元素個數
rbegin ,返回的值和end()相同
rend() ,返回的值和rbegin()相同
count() 用來查找set中某個某個鍵值出現的次數。這個函數在set並不是很實用,因爲一個鍵值在set只可能出現0或1次,這樣就變成了判斷某一鍵值是否在set出現過了。
erase(iterator) ,刪除定位器iterator指向的值
erase(first,second),刪除定位器first和second之間的值
erase(key_value),刪除鍵值key_value的值
find() ,返回給定值值得定位器,如果沒找到則返回end()。 //iter = myset.find(2)
insert(key_value); 將key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool標誌着插入是否成功,而iterator代表插入的位置,若key_value已經在set中,則iterator表示的key_value在set中的位置。
inset(first,second);將定位器first到second之間的元素插入到set中,返回值是void.
在從小到大的排序數組中,
lower_bound( begin,end,num):從數組的begin位置到end-1位置二分查找第一個大於或等於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。
upper_bound( begin,end,num):從數組的begin位置到end-1位置二分查找第一個大於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。
在從大到小的排序數組中,重載lower_bound()和upper_bound()
lower_bound( begin,end,num,greater<type>() ):從數組的begin位置到end-1位置二分查找第一個小於或等於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。
upper_bound( begin,end,num,greater<type>() ):從數組的begin位置到end-1位置二分查找第一個小於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在數組中的下標。
lower_bound( begin,end,num):#include<algorithm> lower_bound( begin,end,num)有三個參數
myset.lower_bound(num) set自帶的lower_bound(num) 只有一個參數
upper_bound( begin,end,num): #include<algorithm> upper_bound( begin,end,num)有三個參數
myset.upper_bound(num): #include<algorithm> upper_bound( begin,end,num)有三個參數
調用的時候和集合的排序順序有關
遞減排序時: set:49 42 40 35 31 20 10 5
cout << *lower_bound(myset.begin(), myset.end(), val) << endl;
cout << *upper_bound(myset.begin(), myset.end(), val) << endl;
cout << *myset.lower_bound(val) << endl;
cout << *myset.upper_bound(val) << endl;
val=30:輸出: 49 49 20 20
遞增排序時: set:5 10 20 31 35 40 42 49
cout << *lower_bound(myset.begin(), myset.end(), val) << endl;
cout << *upper_bound(myset.begin(), myset.end(), val) << endl;
cout << *myset.lower_bound(val) << endl;
cout << *myset.upper_bound(val) << endl;
val=30:輸出: 31 31 31 31
自定義比較函數:
元素不是結構體:
struct myComp
{
bool operator()(const int &a,const int &b) const { **//參數列表之後必須加const**
return a.data-b.data>0;
}
}
set<int,myComp> myset;
元素是結構體:
struct Info
{
string name;
float score;
//重載“<”操作符,自定義排序規則
bool operator < (const Info &a) const {
//按score從大到小排列
return a.score<score;
}
}
set<Info> myset;