amp和set

来源:互联网 发布:易我数据恢复官网 编辑:程序博客网 时间:2024/06/06 07:50
1.map和set是两个主要的关联容器。
2.关联容器和顺序容器的区别:
(1)关联容器中的元素是按照关键字来保存和访问的;
(2)顺序容器中的元素是按照它们在容器中的位置来顺序保存和访问的。 
3.map和set的底层都是通过红黑树来实现的,即中序遍历得到的序列是关键字的升序排列。
一.set 
(1)
容器中只含有关键字,并且关键字不可以重复。

通过以下代码,让我们来具体了解set怎么使用,以及了解set中一些函数的作用,参数以及返回值。

void PrintSet(set<int>& s){    set<int>::iterator iteSet = s.begin();    while(iteSet != s.end())//通过迭代器打印map关键字    {        cout<<*iteSet<<" ";        ++iteSet;    }    cout<<endl;}void TestSet(){    set<int> setName;    setName.insert(2);    setName.insert(5);    setName.insert(7);    setName.insert(8);    setName.insert(6);    PrintSet(setName);    cout<<setName.count(10)<<endl;//count()寻找关键字,如果给定的值存在,返回1;不存在,返回0    setName.erase(6);//删除关键字6    if(setName.find(6) == setName.end())    {        cout<<"12不存在"<<endl;    }    PrintSet(setName);//删除以后再次打印}
(2)
我们知道,顺序容器支持下标操作,set和顺序容器不同,set不支持下标操作. 
1)find函数:如果要找到的关键字存在,返回指向该关键字的迭代器;如果不存在,返回容器中最后一个元素的下一个位置。 
2)set的关键字是const类型的,因此,set的关键字是不可以改变的,只能读不能写,但是根据编译器的不同,也会有所不同
按照顺序打印的结果都是按照关键字升序排列的,那么如何使得打印出的结果是降序的,我们有几种方法:仿函数;反向迭代器。
以下给出用反向迭代器让打印结果降序排列(其实用法和前面的一模一样):

void ReversePrintSet(set<int> s)//用反向迭代器让打印结果降序排列{set<int>::reverse_iterator reIte = s.rbegin();while(reIte != s.rend()){cout<<*reIte<<" ";++reIte;}cout<<endl;}
二:map
(1)map 
map和set有一点区别,set中只存关键字,而map中存储的不仅仅是关键字,还存在关键字所对应的值。
也就是我们之前学过的key-value类型。
所以map中的每一个元素都是pair类型。
pair是一个结构体,pair里边有两个成员:①K类型的first;②V类型的second。
创建pair类型的对象有以下几种方法:
①pair<string,int>("苹果",1);
②make_pair("橘子",2);
③pair<string,int> p = {"香蕉",3};
在以下的代码中我通一用第一种方法------①pair<string,int>("苹果",1);
(2)下面我们通过代码来学习如何使用map中的函数
void TestMap(){map<string,int> mapName;//创建一个map对象mapName,里面的每个元素都是pair<string,int>类型//插入元素mapName.insert(pair<string,int>("苹果",1));mapName.insert(pair<string,int>("香蕉",3));mapName.insert(pair<string,int>("西瓜",2));mapName.insert(pair<string,int>("橘子",4));PrintMap(mapName);//打印map中的元素//查找map<string,int> ::iterator ite1;//定义迭代器ite1ite1 = mapName.find(string("苹果"));//寻找苹果if(ite1 != mapName.end())cout<<"苹果被找到"<<endl;ite1 = mapName.find(string("西瓜"));//寻找西瓜if(ite1 == mapName.end())cout<<"西瓜没有找到"<<endl;//修改某个关键字key的值valuemap<string,int> ::iterator ite2;//定义迭代器ite2ite2 = mapName.find(string("橘子"));//先寻找橘子if(ite2 != mapName.end())//如果寻找到了{ite2->second = 5;//将橘子改成5号}PrintMap(mapName);//再次打印map中的元素ReversePrintMap(mapName);//反向打印}void PrintMap(const map<string,int>& m)//正常打印---升序{map<string,int>::const_iterator iteMap = m.begin();//因为传进来m是const,所以迭代器也要用const类型的while(iteMap != m.end()){cout<<(*iteMap).first<<":"<<(*iteMap).second<<endl;++iteMap;}cout<<endl;}void ReversePrintMap(map<string,int> m)//使用反向迭代器使打印结果变成降序{map<string,int>::reverse_iterator reIte = m.rbegin();while(reIte != m.rend()){cout<<reIte->first<<":"<<reIte->second<<endl;++reIte;}cout<<endl;}
(3)map的应用
①map经常被用在很多方面。比如:
●统计一篇文章中单词出现的次数,
●统计班级同学喜欢吃的水果以及喜欢该水果的人数等等。
下面给出统计吃水果的例子的实现代码:
//统计班级学生喜欢吃的水果
①▼
void CountFavoriteFruits_1(vector<string> v){map<string ,int> countMap;for(size_t i = 0; i < v.size(); ++i){map<string,int>::iterator ret = countMap.find(v[i]);//先查找v[i]是否已经存在if(ret != countMap.end())//已经存在{ret->second++;}else//没有存在,进行插入{countMap.insert(pair<string,int>(v[i],1));}}}

这种方法是可以统计出结果的,但是整个过程会遍历map两次(find遍历一次,insert遍历一次)。
先查找,如果原来已经存在,那么给对应的second加1即可,如果不存在,将其插入。

②▼

void CountFavoriteFruits_2(vector<string> v){map<string,int> countMap;for(size_t i = 0; i< v.size(); ++i){//insert()的实现原理:如果存在,则返回要插入元素所在的位置,以及false;如果不存在,则进行插入pair<map<string,int>::iterator,bool> ret = countMap.insert(pair<string,int>(v[i],1));if(ret.second == false)//表明没有插入成功{ret.first->second ++;}}}

这种方法中 ,我们巧用insert的返回值,●如果不存在,插入,返回指向插入位置的迭代器以及true;
●如果存在,返回指向已经存在位置的迭代器 和flase,然后将其对应second加1即可。

③▼

void CountFavoriteFruits_3(vector<string> v){map<string,int> countMap;for(size_t i = 0; i < v.size(); ++i){//operator[],没有则进行插入,有则返回value的引用countMap[v[i]]++;}SelectTop3(countMap);}
●我们知道operator[]执行两个操作:
①是读(读取关键字),②是写(修改second的值)。
operator[]的参数是给定的关键字key,返回的是key对应的pair的second的类型的引用。 
●at操作:访问所给关键字的元素,带参数检查,如果所给关键字不在map中,则会抛出异常~ 
通过以上3种方法,我们求出了各种水果出现过的次数,
④▼接下来求出现次数最多的几种水果,我们可以采取以下的方法:

bool SortByM1( const pair<string,int> &v1, const pair<string,int> &v2){  return v1.second > v2.second;//降序排列  } void SelectTop3(map<string , int>& m){map<string,int>::iterator ite = m.begin();vector<pair<string,int>>v;while(ite != m.end()){//v.push_back(pair<string,int>((*ite).first,(*ite).second));v.push_back(*ite);++ite;}std::sort(v.begin(),v.end(),SortByM1);}

这种方法是在pair<string,int>类型的vector中放入的是pair类型元素,一定要注意sort的参数。
●我们不能直接对map进行调用sort~~ 
pair是一个结构体,push操作效率不高,我们可以在vector中放指向map的迭代器~代码如下:

void SelectTop3(map<string , int>& m){map<string,int>::iterator ite = m.begin();vector<map<string,int>::iterator> v;while(ite != m.end()){v.push_back(ite);++ite;}struct Compare{bool operator()(map<string,int>::iterator l,map<string,int>::iterator r){return l->second > r->second;}};std::sort(v.begin(),v.end(),Compare());}






0 0
原创粉丝点击