C++中的STL中map⽤法详解
Map是STL的⼀个关联容器,它提供⼀对⼀(其中第⼀个可以称为关键字,每个关键字只能在map中出现⼀次,第⼆个可能称为该关键字的值)的数据处理能⼒,由于这个特性,它完成有可能在我们处理⼀对⼀数据的时候,在编程上提供快速通道。这⾥说下map内部数据的组织,map内部⾃建⼀颗红⿊树(⼀种⾮严格意义上的平衡⼆叉树),这颗树具有对数据⾃动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
1、map简介
map是⼀类关联式容器。它的特点是增加和删除节点对迭代器的影响很⼩,除了那个操作节点,对其他的节点都没有什么影响。
对于迭代器来说,可以修改实值,⽽不能修改key。
2、map的功能
⾃动建⽴Key-value的对应。key 和 value可以是任意你需要的类型。
根据key值快速查记录,查的复杂度基本是Log(N),如果有1000个记录,最多查10次,1,000,000个记录,最多查20次。
快速插⼊Key -Value 记录。
快速删除记录
根据Key 修改value记录。
遍历所有记录。
3、使⽤map
使⽤map得包含map类所在的头⽂件
#include <map> //注意,STL头⽂件没有扩展名.h
map对象是模板类,需要关键字和存储对象两个模板参数:
std:map<int,string> personnel;
这样就定义了⼀个⽤int作为索引,并拥有相关联的指向string的指针.
为了使⽤⽅便,可以对模板类进⾏⼀下类型定义,
typedef map<int,CString> UDT_MAP_INT_CSTRING;
UDT_MAP_INT_CSTRING enumMap;
4、map的构造函数
map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下⾯我们将接触到⼀些map的构造⽅法,这⾥要说下的就是,我们通常⽤如下⽅法构造⼀个map:
map<int, string> mapStudent;
5、数据的插⼊
在构造map容器后,我们就可以往⾥⾯插⼊数据了。这⾥讲三种插⼊数据的⽅法:
第⼀种:⽤insert函数插⼊pair数据,下⾯举例说明(以下代码虽然是随⼿写的,应该可以在VC和GCC下编译通过,⼤家可以运⾏下看什么效果,在VC下请加⼊这条语句,屏蔽4786警告#pragma warning (disable:4786) )
//数据的插⼊--第⼀种:⽤insert函数插⼊pair数据
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, "student_one"));
mapStudent.insert(pair<int, string>(2, "student_two"));
mapStudent.insert(pair<int, string>(3, "student_three"));
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != d(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
}
第⼆种:⽤insert函数插⼊value_type数据,下⾯举例说明
//第⼆种:⽤insert函数插⼊value_type数据,下⾯举例说明
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(map<int, string>::value_type (1, "student_one"));
mapStudent.insert(map<int, string>::value_type (2, "student_two"));
mapStudent.insert(map<int, string>::value_type (3, "student_three"));
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != d(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
}
第三种:⽤数组⽅式插⼊数据,下⾯举例说明
//第三种:⽤数组⽅式插⼊数据,下⾯举例说明
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[2] = "student_two";
mapStudent[3] = "student_three";
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != d(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
}
以上三种⽤法,虽然都可以实现数据的插⼊,但是它们是有区别的,当然了第⼀种和第⼆种在效果上是完成⼀样的,⽤insert函数插⼊数据,在数据的插⼊上涉及到集合的唯⼀性这个概念,即当map中有这个关键字时,insert操作是插⼊数据不了的,但是⽤数组⽅式就不同了,它可以覆盖以前该关键字对应的值,⽤程序说明:
mapStudent.insert(map<int, string>::value_type (1, "student_one"));
mapStudent.insert(map<int, string>::value_type (1, "student_two"));
上⾯这两条语句执⾏后,map中1这个关键字对应的值是“student_one”,第⼆条语句并没有⽣效,那么这就涉及到我们怎么知道insert语句是否插⼊成功的问题了,可以⽤pair来获得是否插⼊成功,程序如下:
pair<map<int, string>::iterator, bool> Insert_Pair;
Insert_Pair = mapStudent.insert(map<int, string>::value_type (1, "student_one"));
我们通过pair的第⼆个变量来知道是否插⼊成功,它的第⼀个变量返回的是⼀个map的迭代器,如果插⼊成功的话Insert_Pair.second应该是true的,否则为false。
下⾯给出完成代码,演⽰插⼊成功与否问题:
//验证插⼊函数的作⽤效果
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
pair<map<int, string>::iterator, bool> Insert_Pair;
Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_one"));
if(Insert_Pair.second == true)
cout<<"Insert Successfully"<<endl;
elseenum怎么用
cout<<"Insert Failure"<<endl;
Insert_Pair = mapStudent.insert(pair<int, string>(1, "student_two"));
if(Insert_Pair.second == true)
cout<<"Insert Successfully"<<endl;
else
cout<<"Insert Failure"<<endl;
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != d(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
}
⼤家可以⽤如下程序,看下⽤数组插⼊在数据覆盖上的效果:
//验证数组形式插⼊数据的效果
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent[1] = "student_one";
mapStudent[1] = "student_two";
mapStudent[2] = "student_three";
map<int, string>::iterator iter;
for(iter = mapStudent.begin(); iter != d(); iter++)
cout<<iter->first<<' '<<iter->second<<endl;
}
6、map的⼤⼩
在往map⾥⾯插⼊了数据,我们怎么知道当前已经插⼊了多少数据呢,可以⽤size函数,⽤法如下:Int nSize = mapStudent.size();
7、数据的遍历
这⾥也提供三种⽅法,对map进⾏遍历
第⼀种:应⽤前向迭代器,上⾯举例程序中到处都是了,略过不表
第⼆种:应⽤反相迭代器,下⾯举例说明,要体会效果,请⾃个动⼿运⾏程序
//第⼆种,利⽤反向迭代器
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, "student_one"));
mapStudent.insert(pair<int, string>(2, "student_two"));
mapStudent.insert(pair<int, string>(3, "student_three"));
map<int, string>::reverse_iterator iter;
for(iter = mapStudent.rbegin(); iter != d(); iter++)
cout<<iter->first<<" "<<iter->second<<endl;
}
第三种,⽤数组的形式,程序说明如下:
//第三种:⽤数组⽅式,程序说明如下
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, "student_one"));
mapStudent.insert(pair<int, string>(2, "student_two"));
mapStudent.insert(pair<int, string>(3, "student_three"));
int nSize = mapStudent.size();
//此处应注意,应该是 for(int nindex = 1; nindex <= nSize; nindex++)
//⽽不是 for(int nindex = 0; nindex < nSize; nindex++)
for(int nindex = 1; nindex <= nSize; nindex++)
cout<<mapStudent[nindex]<<endl;
}
8、查并获取map中的元素(包括判定这个关键字是否在map中出现)
在这⾥我们将体会,map在数据插⼊时保证有序的好处。
要判定⼀个数据(关键字)是否在map中出现的⽅法⽐较多,这⾥标题虽然是数据的查,在这⾥将穿插着⼤量的map基本⽤法。
这⾥给出三种数据查⽅法
第⼀种:⽤count函数来判定关键字是否出现,其缺点是⽆法定位数据出现位置,由于map的特性,⼀对⼀的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了
第⼆种:⽤find函数来定位数据出现位置,它返回的⼀个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查的数据,它返回的迭代器等于end函数返回的迭代器。
查map中是否包含某个关键字条⽬⽤find()⽅法,传⼊的参数是要查的key,在这⾥需要提到的是begin()和end()两个成员,
分别代表map对象中第⼀个条⽬和最后⼀个条⽬,这两个数据的类型是iterator.
程序说明:
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent.insert(pair<int, string>(1, "student_one"));
mapStudent.insert(pair<int, string>(2, "student_two"));
mapStudent.insert(pair<int, string>(3, "student_three"));
map<int, string>::iterator iter;
iter = mapStudent.find(1);
if(iter != d())
cout<<"Find, the value is "<<iter->second<<endl;
else
cout<<"Do not Find"<<endl;
return 0;
}
通过map对象的⽅法获取的iterator数据类型是⼀个std::pair对象,包括两个数据 iterator->first和 iterator->second分别代表关键字和存储的数据。
第三种:这个⽅法⽤来判定数据是否出现,是显得笨了点,但是,我打算在这⾥讲解upper_bound函数⽤法,这个函数⽤来返回要查关键字的上界(是⼀个迭代器)
例如:map中已经插⼊了1,2,3,4的话,如果lower_bound(2)的话,返回的2,⽽upper-bound(2)的话,返回的就是3
Equal_range函数返回⼀个pair,pair⾥⾯第⼀个变量是Lower_bound返回的迭代器,pair⾥⾯第⼆个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,
程序说明:
#include <map>
#include <string>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论