stl库的map

map的使用

声明:本文仅作为个人学习记录,如有侵权,请联系删除!谢谢!
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,
每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,
由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。
这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),
这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。

map的特点

1、存储Key-value对

2、支持快速查找,查找的复杂度基本是Log(N)

3、快速插入,快速删除,快速修改记

map一共提供了6个构造函数

map<string ,int>mapstring;

map<int,string >mapint;

map<sring,char>mapstring;

map< char ,string>mapchar;

map<char,int>mapchar;

map<int ,char>mapint;

数据的插入(与插入的顺序无关,自动排序)

  1. 1.用insert函数插入pair数据
#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;//第一个是key值,按key值排序的 
mp.insert(pair<int,string>(3,"student_three"));
mp.insert(pair<int,string>(1,"student_one"));
mp.insert(pair<int,string>(2,"student_two"));
map<int,string>::iterator it;//迭代器 
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n";

/*map<string,int>mp;
mp.insert(pair<string,int>("c",3));
mp.insert(pair<string,int>("a",1));
mp.insert(pair<string,int>("b",2));
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n";*/ 

}
  1. 2.用数组方式插入数据,mp.size()计算map的大小
#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
mp[1]="student_one";
mp[2]="student_two";
mp[3]="student_three";
map<int,string>::iterator it;//迭代器 
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n";
cout<<(mp.size())<<"\n";
}

map中不能修改key,可以用pair来判断是否插入成功

#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
pair<map<int,string>::iterator,bool>insert_pair;
insert_pair=mp.insert(pair<int,string>(1,"student_one"));
if(insert_pair.second==true)
cout<<"insert successfully\n";
else
cout<<"insert failure\n";
insert_pair=mp.insert(pair<int,string>(1,"student_two"));
if(insert_pair.second==true)
cout<<"insert successsfully\n";
else
cout<<"insert failure\n";
map<int,string>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
{
cout<<it->first<<" "<<it->second<<"\n";
}
}

map中的遍历

  1. 1.使用反向迭代器可以让map里的数据反向遍历
#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
mp.insert(pair<int,string>(1,"student_one"));
mp.insert(pair<int,string>(3,"student_three"));
mp.insert(pair<int,string>(2,"student_two"));
cout<<"map的大小\n";
cout<<mp.size()<<"\n";
cout<<"使用反向迭代器\n";
map<int,string>::reverse_iterator it;
for(it=mp.rbegin();it!=mp.rend();it++)
cout<<it->first<<" "<<it->second<<"\n";
cout<<"使用正向迭代器\n";
map<int,string>::iterator it1;
for(it1=mp.begin();it1!=mp.end();it1++)
{
cout<<it1->first<<" "<<it1->second<<"\n";
} 


}
  1. 2.使用数组方式来实现map的遍历
#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
mp.insert(pair<int,string>(1,"student_one"));
mp.insert(pair<int,string>(3,"student_three"));
mp.insert(pair<int,string>(2,"student_two"));
int idex=mp.size();
for(int i=1;i<=idex;i++)
cout<<i<<" "<<mp[i]<<"\n";
for(int i=idex;i>0;i--)
cout<<i<<" "<<mp[i]<<"\n";
}

在map里查找并获取map里的元素,判断这个关键字是否在map里出现过

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,
由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,
要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,
它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等
于end函数返回的迭代器。

查找map中是否包含某个关键字条目用find()方法,传入的参数是要查找的key,
在这里需要提到的是begin()和end()两个成员,
分别代表map对象中第一个条目和最后一个条目,这两个数据的类型是iterator.

#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
mp.insert(pair<int,string>(1,"student_one"));
mp.insert(pair<int,string>(3,"student_three"));
mp.insert(pair<int,string>(2,"student_two"));
map<int,string>::iterator it;
it=mp.find(1);
if(it!=mp.end())
cout<<"find,the value is "<<it->second<<"\n";//这里用it->first会显示出它的key值 
else
cout<<"No find"<<"\n";
//cout<<mp.count(4)<<"\n"; 
} */

lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)

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<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
mp[1]="student_one";
mp[3]="student_three";
mp[5]="student_five";
map<int,string>::iterator it;
it=mp.lower_bound(1);
cout<<it->second<<"\n";//student_one 返回的是下界为1的迭代器 
it=mp.lower_bound(2);
cout<<it->second<<"\n";// student_three 返回的是下界为3的迭代器 
it=mp.lower_bound(3); 
cout<<it->second<<"\n";// student_three 返回的是下界为3的迭代器
it=mp.upper_bound(3);
cout<<it->second<<"\n";// student_five 返回的是上界为5的迭代器 
it=mp.upper_bound(2);
cout<<it->second<<"\n";// student_three 返回的是上界为3的迭代器 
pair<map<int,string>::iterator,map<int,string>::iterator>pair_1;
pair_1=mp.equal_range(2);
if(pair_1.first==pair_1.second)
cout<<"no find"<<"\n";
else
cout<<"find"<<"\n";
pair_1=mp.equal_range(3);
if(pair_1.first==pair_1.second)
cout<<"no find"<<"\n";
else
cout<<"find"<<"\n";

}

在map中删除元素

移除某个map中某个条目用erase()

该成员方法的定义如下:
iterator erase(iterator it);//通过一个条目对象删除

iterator erase(iterator first,iterator last)//删除一个范围

size_type erase(const Key&key);//通过关键字删除

clear()就相当于enumMap.erase(enumMap.begin(),enumMap.end());

#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<int,string>mp;
mp.insert(pair<int,string>(1,"student_one"));
mp.insert(pair<int,string>(2,"student_two"));
mp.insert(pair<int,string>(3,"student_three"));

map<int,string>::iterator it;
//迭代器删除
it=mp.find(1);
mp.erase(it);
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n"; 
//关键字删除,如果删除了返回1,否则返回0 
int n=mp.erase(2);
cout<<n<<"\n";
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n";
//范围删除

mp.erase(mp.begin(),mp.end());
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n"; 

}

map中的sort问题

map中的元素是自动按Key升序排序,所以不能对map用sort函数;

STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,
因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,
比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,
insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。

小于号重载

#include<bits/stdc++.h>
using namespace std; 
typedef struct tagStudentinfo 
{ 
int niD; 
string strName; 
bool operator < (tagStudentinfo const& _A) const 
{ //这个函数指定排序策略,按niD排序,如果niD相等的话,按strName排序 
if(niD < _A.niD) return true; 
if(niD == _A.niD) 
return strName.compare(_A.strName)<0; 
return false; 
} 
}Studentinfo, *PStudentinfo; //学生信息 
int main() 
{ 
int nSize; //用学生信息映射分数 
map<Studentinfo, int>mapStudent; 
map<Studentinfo, int>::iterator iter; 
Studentinfo studentinfo; 
studentinfo.niD = 1; 
studentinfo.strName = "student_one"; 
mapStudent.insert(pair<Studentinfo, int>(studentinfo, 90)); 
studentinfo.niD = 2; 
studentinfo.strName = "student_two"; 
mapStudent.insert(pair<Studentinfo, int>(studentinfo, 80)); 
for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++) 
cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl; 
return 0; 
}

map题目

MD5是一种信息摘要算法,它可以对任意大小的文件产生等长的密钥,当你在A主机使用MD5得
到文件X的密钥后,在B主机同样对文件X使用MD5所得到密钥一定与A主机所得到的密钥相同。
然后请实现MD5算法。
是的,我在开玩笑。
恩,我实现了一个MD6算法,它可以实现类似的功能。

本题包含多组样例。

输入第一行为数字N和Q,N为映射的行数,Q为询问的行数。

映射中每行包含一个字符串A(0<alen<30),和字符串A使用MD6算法对应的数字。

询问每行包含一个字符串A。

输出每个询问行中每个字符串使用MD6算法对应的数字。

5 3

fs3fwe 3

4838fdeewerwer 54

irjfhid 888

847hhhh 1

0000 0

0000

847hhhh

fs3fwe

0

1

3

#include<bits/stdc++.h>
using namespace std;
#include<map>
int main()
{
map<string,int>mp;
int n,m,num,flag;
string A,B;
while(cin>>n>>m)
{
mp.clear();
for(int i=0;i<n;i++)
{
cin>>A>>num;
mp[A]=num;
}
for(int i=0;i<m;i++)
{
cin>>B;
cout<<mp[B]<<"\n";
}
}

}

某次张国庆脑袋抽筋时想到了n个自然数,每个数均不超过1500000000(1.5*109)。

已知不相同的数不超过10000个,现在需要统计这些自然数各自出现的次数,并按照
自然数从小到大的顺序输出统计结果。

输入包含n+1行:
第1行是整数n,表示自然数的个数。
第2~n+1行每行一个自然数。

输入
8
2
4
2
4
5
100
2
100

输出
2 3
4 2
5 1
100 2

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
map<int,int>mp;
ll n,num;
cin>>n;
while(n--)
{
cin>>num;
mp[num]++;
}
map<int,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second<<"\n";
}

得克萨斯州的一个小镇Doubleville,被外星人攻击。他们绑架了当地人并把他
们带到飞船里。经过一番(相当不愉快的)人体实验,外星人克隆了一些 受害者
,并释放了其中的多个副本回Doubleville。所以,现在有可能发生有6个人:原
来的人和5个复制品都叫做Hugh F. Bumblebee。现在FBUC美国联邦调查局命令你
负责确定每个人被复制了多少份,为了帮助您完成任务,FBUC收集每个人的DNA样
本。同副本和原 来的人具有相同的DNA序列,不同的人有不同的序列(我们知道
,城里没有同卵双胞胎,这不是问题)

Input

输入中含有多组数据,每一组以一行n m开始,表示共有n个人1 ≤ n ≤ 20000,
其中DNA序列长度为m, 1 ≤ m ≤ 20. 接下来的n行为DNA序列:每行包含m个字
符,字符为'A','C','G'或'T'。 输入以n=m=0 结尾。

Output

每一组数据应输出n行,每行一个整数。第一行表示有几个人没有被复制,
第二行表示有几个人只被复制一次(也就是说有两个相同的人),第三行表示有几个是被复制两次,依次类推,第i行表示其中有i个相同的人的共有几组。

举例来说,如果有11个样本,其中之一是John Smith,和所有其余的都是从Joe
Foobar复制来的副本,那么你必须打印第一行和第10行输出1,其余行输出0。
Sample Input

9 6

AAAAAA

ACACAC

GTTTTG

ACACAC

GTTTTG

ACACAC

ACACAC

TCCCCC

TCCCCC

0 0

Sample Output

1
2
0
1
0
0
0
0
0

#include<bits/stdc++.h>
using namespace std;
#include<map>
int cnt[10005];
int main()
{
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
int n,m;
string s;
map<string,int>mp;
while((scanf("%d%d",&n,&m)!=EOF)&&n!=0&&m!=0)
{
for(int i=0;i<n;i++)
{
cin>>s;
mp[s]++;
cnt[i]=0;
s.clear();
}
map<string,int>::iterator it;
for(it=mp.begin();it!=mp.end();it++)
cnt[it->second]++;
for(int i=1;i<=n;i++)
cout<<cnt[i]<<"\n";
mp.clear();
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值