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; 

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