STL 之map 与pair 与unordered_map 常⽤函数详解
STL 之map 与pair 与unordered_map 常⽤函数详解
⼀、map 的概述
map 是STL 的⼀个关联容器,它提供⼀对⼀(其中第⼀个可以称为关键字,每个关键字只能在map 中出现⼀次,第⼆个可能称为该关键字的值)的数据处理能⼒,由于这个特性,它完成有可能在我们处理⼀对⼀数据的时候,在编程上提供快速通道。这⾥说下map 内部数据的组织,map 内部⾃建⼀颗红⿊树(⼀种⾮严格意义上的平衡⼆叉树),这颗树具有对数据的功能,所以在map 内部所有的数据都是有序的,后边我们会见识到有序的好处。
众所周知,在定义数组的时候⽐如(int array[10]) ,array[0]=25,array[1]=10,其实就是⼀个映射,将0—>25,1—>10,就是将0映射到25,将1映射到10,这种⼀⼀对应的关系就是映射,就数组来说,他的下标和其下标所对应的值就是⼀种映射关系,但是这⼀种关系⽐较死板,于是就有map ,这⼀种容器,。
⼆、map 的定义与初始化(插⼊)
单独定义⼀个map :
typename1是键值的数据类型
typename2是值的数据类型
如果是字符串映射到整型数组,键值必须使⽤string 类型,⽽不能使⽤char 数组。
这是因为char 作为数组,不能作为键值。
map 的键和值可以是STL 的容器,我们将set 映射到⼀个字符串三、map 的元素的访问
map 中的容器值可以通过:下标和迭代器进⾏访问。
下标访问map 键值是唯⼀的
通过迭代器访问
map 的迭代器与其他STL 容器相同
下⾯来看⼀个⽰例:
⾃动排序下⾯举例说明:
map 可以建⽴将任何基本类型(包括STL 容器)映射到任何基本数据类型(包括STL 容器)//  引⼊⼀个头⽂件
#include <map>
map<typename1,typename2> mp;
map<set<int>,string> mp;
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{    map<char,int> mp;
mp['c']=20;
mp['c']=30;  //  由于键值唯⼀,第⼀个他的值将会被覆盖
cout<<mp['c']<<endl;
return 0;
}
//  输出
30
map<typename1,typename2>::iterator it;
//  由于⼀个it 对应两个值,我们使⽤  it->first  访问键  it->second  访问值
PS :下⾯我以3种不同的⽅式进⾏插⼊不懂得可以参照这⼀篇⽂章:
//  以类似数组的的表达⽅式来进⾏
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<char,int> mp;
char key;
int val;
int t=5;
while(t--)
{
cin>>key>>val;
mp[key]=val;
}
//  通过迭代器来访问
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
a 5
s 8
z 6
p 3
t 7
a 5
p 3
s 8
t 7
z 6
其实细⼼的⼩伙伴已经发现,其输出结果是按照键值进⾏升序排序的。中有,以来代替实现,其,了。下⾯会有介绍。
⽤insert 函数插⼊数据,下⾯举例说明
z 6
C++11unordered_map 散列map 内部的红⿊树不需要排序速度就 快很多#include <iostream>#include <map>
#include <string>
using namespace std;
int main()
{
map<char,int> mp;
char key;
int val;
int t=5;
while(t--)
{
cin>>key>>val;
mp.insert(make_pair(key,val));  // 以make_pair 来插⼊
}
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<char,int> mp;
char key;
int val;
int t=5;
while(t--)
{
cin>>key>>val;
mp.insert(pair<char,int>(key,val));  //  以pair 来插⼊
}
for(map<char,int>::iterator it=mp.begin();it!=mp.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main()
{
map<char,int> mp;
char key;
int val;
int t=5;
while(t--)
{
cin>>key>>val;
mp.insert(pair<char,int>(key,val));
}
//  这种基于范围的for 循环,只有C++11以上才可以
for(auto it=mp.begin();it!=mp.end();it++)
{
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
value_type #include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));
mapStudent.insert(map<int,string>::value_type(3,"student2"));
for(map<int,string>::iterator it=mapStudent.begin();it!=d();it++)
cout<<it->first<<" "<<it->second<<endl;
return 0;
}
四.map 常⽤函数解析⽤find 函数来定位数据出现位置,它返回的⼀个迭代器,当数据出现时,它返回数
据所在位置的迭代器,如果map 中没有要查的数据,它返回的迭代器等于end 函数返回的迭代器,程序说明:删除元素有两种⽅法:删除单个元素;删除⼀个区间的元素。
删除单个元素:mp.erase(it), it 为要删除的元素的迭代器
通过键值来删除⼀个元素:
//  输出结果:
G:\clion\qifei\
1 student1
2 student2
3 student2
Process finished with exit code 0
find()#include <iostream>
#include <map>
#include <string>
字符串函数注册登录using namespace std;
int main() {    map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));    mapStudent.insert(map<int,string>::value_type(3,"student2"));
map<int,string>::iterator pter=mapStudent.find(2);
cout<<pter->first<<" "<<pter->second<<endl;
return 0;
}
//  输出结果:
2 student2
erase()#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));    mapStudent.insert(map<int,string>::value_type(3,"student2"));
map<int,string>::iterator pter=mapStudent.find(2);
for(map<int,string>::iterator it=mapStudent.begin();it!=d();it++)
cout<<it->first<<" "<<it->second<<endl;
return 0;
}
//  输出结果:
1 student1
3 student2
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));
mapStudent.insert(map<int,string>::value_type(3,"student2"));
map<int,string>::iterator pter=mapStudent.find(2);
for(map<int,string>::iterator it=mapStudent.begin();it!=d();it++)
cout<<it->first<<" "<<it->second<<endl;
return 0;
}
/
/ 输出结果:
1 student1
3 student2
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));
mapStudent.insert(map<int,string>::value_type(3,"student3"));
mapStudent.insert(map<int,string>::value_type(4,"student4"));
mapStudent.insert(map<int,string>::value_type(5,"student5"));
mapStudent.insert(map<int,string>::value_type(6,"student6"));
mapStudent.insert(map<int,string>::value_type(7,"student7"));
map<int,string>::iterator pter=mapStudent.find(4);
for(map<int,string>::iterator it=mapStudent.begin();it!=d();it++)
size() ,可以获取map 中的映射对数。
clear(),请空所有的元素。
map 和unordered_map 的使⽤unordered_map 的⽤法和map 是⼀样的,提供了 insert ,size ,count
等操作,并且⾥⾯的元素也是以pair 类型来存贮的。其底层实现是完全不同的,上⽅已经解释了,但是就。
map 和unordered_map 的差别
需要引⼊的头⽂件不同
内部实现机理不同
map : map 内部实现了⼀个红⿊树(红⿊树是⾮严格平衡⼆叉搜索树,⽽AVL 是严格平衡⼆叉搜索树),红⿊树具有⾃动排序的功能,因此map 内部的所有元素都是有序的,红⿊树的每⼀个节点都代表着map 的⼀个元素。因此,对于map 进⾏的查,删除,添加等⼀系列的操作都相当于是对红⿊树进⾏的操作。map 中的元素是按照⼆叉搜索树(⼜名⼆叉查树、⼆叉排序树,特点就是左⼦树上所有节点的键值都⼩于根节点的键值,右⼦树所有节点的键值都⼤于根节点的键值)存储的,使⽤中序遍历可将键值按照从⼩到⼤遍历出来。
unordered_map : unordered_map 内部实现了⼀个哈希表(也叫散列表,通过把关键码值映射到Hash 表中⼀个位置来访问记录,查的时间复杂度可达到O(1),其在海量数据处理中有着⼴泛应⽤)。因此,其元素的排列顺序是⽆序的。哈希表详细介绍
优缺点以及适⽤处
map :
优点:
有序性,这是map 结构最⼤的优点其元素的有序性在很多应⽤中都会简化很多的操作
红⿊树,内部实现⼀个红⿊书使得map 的很多操作在lgn 的时间复杂度下就可以实现,因此效率⾮常的⾼
缺点:空间占⽤率⾼,因为map 内部实现了红⿊树,虽然提⾼了运⾏效率,但是因为每⼀个节点都需要额外保存⽗节点、孩⼦节点和红/⿊性质,使得每⼀个节点都占⽤⼤量的空间适⽤处:对于那些有顺序要求的问题,⽤map 会更⾼效⼀些
unordered_map :
优点: 因为内部实现了哈希表,因此其查速度⾮常的快
缺点: 哈希表的建⽴⽐较耗费时间
适⽤处:对于查问题,unordered_map 会更加⾼效⼀些,因此遇到查问题,常会考虑⼀下⽤unordered_map
总结:
for(map<int,string>::iterator it=mapStudent.begin();it!=d();it++)
cout<<it->first<<" "<<it->second<<endl;
return 0;
}
//  输出结果:
1 student1
2 student2
3 student3
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));
mapStudent.insert(map<int,string>::value_type(3,"student3"));
mapStudent.insert(map<int,string>::value_type(4,"student4"));
mapStudent.insert(map<int,string>::value_type(5,"student5"));
mapStudent.insert(map<int,string>::value_type(6,"student6"));
mapStudent.insert(map<int,string>::value_type(7,"student7"));
cout<<mapStudent.size()<<endl;
return 0;
}
//  输出结果:
7
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<int, string> mapStudent;
mapStudent.insert(map<int,string>::value_type(1,"student1"));
mapStudent.insert(map<int,string>::value_type(2,"student2"));
mapStudent.insert(map<int,string>::value_type(3,"student3"));
mapStudent.insert(map<int,string>::value_type(4,"student4"));
mapStudent.insert(map<int,string>::value_type(5,"student5"));
mapStudent.insert(map<int,string>::value_type(6,"student6"));
mapStudent.insert(map<int,string>::value_type(7,"student7"));
mapStudent.clear();
cout<<mapStudent.size()<<endl;
return 0;
}
//  输出结果:
(c++11)外部使⽤来说却是⼀致的map: #include < map >
unordered_map: #include < unordered_map >
内存占有率的问题就转化成红⿊树 VS hash表 , 还是unorder_map占⽤的内存要⾼。
但是unordered_map执⾏效率要⽐map⾼很多
对于unordered_map或unordered_set容器,其遍历顺序与创建该容器时输⼊的顺序不⼀定相同,因为遍历是按照哈希表从前往后依次遍历的#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;
int main() {
unordered_map<int, string> mapStudent;
mapStudent.insert(unordered_map<int,string>::value_type(2,"student2"));
mapStudent.insert(unordered_map<int,string>::value_type(4,"student4"));
mapStudent.insert(unordered_map<int,string>::value_type(5,"student5"));
mapStudent.insert(unordered_map<int,string>::value_type(3,"student3"));
mapStudent.insert(unordered_map<int,string>::value_type(7,"student7"));
mapStudent.insert(unordered_map<int,string>::value_type(6,"student6"));
mapStudent.insert(unordered_map<int,string>::value_type(1,"student1"));
for(auto it=mapStudent.begin();it!=d();it++)
cout<<it->first<<" "<<it->second<<endl;
return 0;
}
// 输出结果:
G:\clion\qifei\
1 student1
6 student6
7 student7
2 student2
4 student4
5 student5
3 student3
Process finished with exit code 0

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。