您的位置:首页 > 其它

STL之map容器使用

2016-12-14 23:24 381 查看
一、map是一个关联容器,属于类模版。关联的本质是元素的值和某个特定的键相关联,而不是像数组那样通过元素在数组中的位置来获取。

特点:

1、增加删除节点对迭代器的影响很小;

2、对于迭代器来说不可以更改键值,只能修改其对应的值;

3、map内部数据的组织结构为红黑树,这棵树具有对数据自动排序的功能,所以map内部所有的数据都是有序的;

4、所选键值必须支持<重载;

5、map中存储的元素为pair类型

6、使用[]可能添加新元素 如m[3];当原来不存在key为3时会创建一个元素;

二、pair类型

学习关联容器之前,必须要了解名为pair的标准库,它定义在头文件中,用来保存两个成员数据,注意它也是一个模版,当创建一个pair时,必须提供创建两个类型名,pair的数据成员将具有对应的类型。两个类型不要求一致;

这里我们可以跳进pair源码查看pair的定义;

#include <iostream>
#include <utility>
int main()
{
std::pair<int, string> a;//此时调用pair的默认构造函数对数据成员进行值初始化;这里的值初始化指的是内置类型元素初始化为0,如int初始化为0;类类型元素调用默认构造函数
cout<<a.first<<endl;
cout<<a.second<<endl;

}


三、构造方式:

使用时注意导入头文件

#include <iostream>
#include <map>
int main(int argc ,char* argv[])
{
map<int,string> mapTest1;//构造一个空的map容器
map<int,string> mapTest2{{1,"zhao"},{2,"qian"}};//使用列表初始化map容器
map<int,string> mapTest3{pair<int,string>(1,"zhao")};//使用pair初始化;
map<int,string> mapTest4(mapTest3.begin(),mapTest4.end());//使用迭代器初始化;
map<int,string> mapTest5(mapTest2);//使用已有对象初始化map容器
}


四、插入操作

1、使用函数insert(),同一个key有数据之后insert将失败;

2、使用数组方式插入,则会直接覆盖掉原来的值;

int main(int argc, const char * argv[])
{

map<int,string> mapTest{pair<int, string>(1,"gg"),{2,"tt"}};
mapTest.insert({2,"heh"});//插入失败,不报错,只是插入不成功
mapTest[1] = "xx";//覆盖掉原来的键(key)'1'对应的值(value)“gg”;
for(auto v:mapTest)
{
cout<<v.first;
cout<<v.second<<endl;
}
return 0;
}


五、遍历操作

1、第一种使用范围for循环

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{2,"tt"}};
for(auto v:mapTest) //注意此时的v为pair类型
{
cout<<v.first;
cout<<v.second<<endl;
}
return 0;
}


2、第二种使用迭代器的方式

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"}};
map<int,string>::iterator itor = mapTest.begin();
while (itor != mapTest.end())
{
cout<<itor->first<<endl;
cout<<itor->second<<endl;
++itor;
}
return 0;
}


3、如果容器的key值为int,使用下标遍历会出现什么问题?

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"}};
for(int i = 1;i <= mapTest.size();++i)
{
cout<<mapTest[i]<<endl;
}
return 0;
//输出的结果有什么问题呢?
}


六、查找操作

1、第一种使用count函数来判断关键字是否出现,缺点是无法确定出现的位置,由于map的一对一映射特点,决定了count函数的返回值只有两个,要么为0,要么为1,当为0时表示不存在,为1时存在

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"}};
if(mapTest.count(2) == 0)
{
cout<<"key为2的元素不存在"<<endl;
}else
{
cout<<"key为2的元素存在"<<endl;
}
return 0;
}


2、使用find()函数定位数据出现的位置,当key值存在时,返回对应位置的迭代器,否则返回end()函数返回的迭代器;

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"}};
auto p = mapTest.find(1);
if(p != mapTest.end())
{
cout<<p->first<<endl;
cout<<p->second<<endl;
}else
{
cout<<"key为1的元素不存在"<<endl;
}
return 0;
}


七、删除操作

1、通过key值来删除元素

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"}};
mapTest.erase(1);
for (auto v : mapTest)
{
cout<<v.first<<endl;
cout<<v.second<<endl;
}
return 0;
}


2、通过迭代器删除

int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"}};
mapTest.erase(mapTest.begin());//删除指定位置
mapTest.erase(mapTest.begin(),--mapTest.end());//删除指定范围
for (auto v : mapTest)
{
cout<<v.first<<endl;
cout<<v.second<<endl;
}
return 0;
}


八、排序操作

学习map排序之前我们要注意,map容器默认将元素按照key值由小到大排序;

1、使用库函数实现按照key从大到小排序

int main(int argc, const char * argv[])
{
map<int,string,greater<int>> mapTest{{1,"gg"},{3,"tt"},{4,"aa"}};
for (auto v: mapTest)
{
cout<<v.first<<endl;
}
return 0;
}


2、自定义实现按照key从小到大排序

struct ComByKey
{
bool operator()(const int& k1,const int& k2)const
{
return k1 > k2;
}
};
int main(int argc, const char * argv[])
{
map<int,string,ComByKey> mapTest{{1,"gg"},{3,"tt"},{4,"aa"}};
for (auto v: mapTest)
{
cout<<v.first<<endl;
}
return 0;
}


3、自定义实现map中的value从小到大排序

主要思路讲map中的元素转存到vector中,在对vector进行排序

typedef pair<int, string> MyPair;
bool comByVal(const MyPair& v1,const MyPair& v2)//定义vector容器的比较规则
{
return v1.second < v2.second;
}
int main(int argc, const char * argv[])
{
map<int,string> mapTest{{1,"gg"},{3,"tt"},{4,"aa"}};
vector<MyPair> V(mapTest.begin(),mapTest.end());
sort(V.begin(), V.end(), comByVal);
for (auto v: V)
{
cout<<v.second<<endl;
}
return 0;
}


九、其他操作

begin() 返回指向map头部的迭代器

end() 返回指向map末尾元素的下一个的迭代器

rbegin() 返回一个指向map尾部的逆向迭代器

rend() 返回一个指向map头部前一个元素的逆向迭代器

size() 返回map中元素的个数

empty() 如果map为空则返回true

clear() 删除所有元素

swap() 交换两个map

lower_bound() 返回键值>=给定key值的第一个元素的迭代器

upper_bound() 返回键值>给定key值的第一个元素的迭代器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stl map操作
相关文章推荐