c++ map和set常用操作

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; 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章