1.map简介:
map是STL中的一个关联式容器,可以建立key(first)和value(second)一对一的联系,由key映射到value
map内部自建了一颗红黑二叉树,可以对数据进行自动排序,所以map里的数据都是有序的,这也是我们通过map简化代码的原因
使用map需要声明头文件#include< map>
2.map特点:
自动建立 key-value的对应关系,key和value可以是我们需要的任何类型
快速查找、删除记录,根据key的值查找的复杂度很低
key和value一一对应关系可以去重
3.map的基本操作
map<int,string>map_student//定义了一个由int映射到string的map
//并命名为map_student
这里的first和second的数据类型可以是任意的数据类型,包括自定义的数据类型。
4.向map中插入数据的方法
//方法1:把map用数组的方式插入数据
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<int,string> map_student;
map_student[1] = "student1";
map_student[1] = "student2";
//可以看出来第二次操作覆盖了第一次key对应的value
map<int,string>::iterator iter;//声明迭代器
iter = map_student.begin();
cout << iter->first << " " << iter->second << endl;
return 0;
}
//方法2:用insert()函数插入数据
/*
(1)insert(map<int,string>::value_type(1,"student1"));
(2)insert(make_pair(1,"student1"));
与方法1不同的是,insert()函数体现了映射的一一对应这一特性
即当map中有这个key时,就不能用insert插入数据了
但是用数组的方法1是可以覆盖原数据的
*/
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<int,string> map_student;
map_student.insert(map<int,string>::value_type(1,"student1"));
map_student.insert(make_pair(1,"student2"));
map_student.insert(make_pair(2,"student2"));
map_student.insert(make_pair(3,"student2"));
cout << map_student[1] << endl;
cout << map_student[2] << endl;
cout << map_student[3] << endl;
return 0;
}
5.map的基本操作函数
begin() //返回指向map首部的迭代器
end() //返回指向map尾部的迭代器
empty() //如果map为空就返回true,反之false
find(n) //返回指向元素n的迭代器
count(n) //统计n出现的次数(0或1),因为1对1
size() //返回map中元素的个数
6.遍历map
//方案1:使用begin()和end()遍历map
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<int,string> map_student;
map_student[1] = "student1";
map_student[3] = "student3";
map_student[2] = "student2";
map<int,string>::iterator iter;//声明迭代器
for(iter = map_student.begin();iter !=map_student.end();iter++)
cout << iter->first << " " << iter->second << endl;
return 0;
}
//方案2:使用数组的方法遍历map
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<int,string> map_student;
map_student[1] = "student1";
map_student[3] = "student3";
map_student[2] = "student2";
map<int,string>::iterator iter;//声明迭代器
for(int i = 1; i <= map_student.size();i++)
cout << i << " " << map_student[i] << endl;
return 0;
}
7.使用find()查找
用find函数来定位数据出现位置它返回一个迭代器
当数据出现时,它返回数据所在位置的迭代器
如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器
#include<iostream>
#include<map>
using namespace std;
int main()
{
map<char,int> my_map;
map<char,int> ::iterator iter;
my_map['a'] = 50;
my_map['b'] = 100;
my_map['c'] = 150;
my_map['d'] = 200;
cout << "a => " << my_map.find('a') ->second << endl;
cout << "b => " << my_map.find('b') ->second << endl;
cout << "c => " << my_map.find('c') ->second << endl;
cout << "d => " << my_map.find('d') ->second << endl;
cout << "e => " << my_map.find('e') ->second << endl;
return 0;
}
8.使用count()函数
count()函数返回的是一个整数,1表示有这个元素,0表示没有这个元素。它无法定位数据出现位置。
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<int,string> my_map;
map<int,string> ::iterator iter;
my_map[1] = "student1";
my_map[2] = "student2";
my_map[3] = "student3";
if(my_map.find(4) == my_map.end())
cout << "没有4这个元素" << endl;
if(my_map.count(4) == 0)
cout << "没有4这个元素" << endl;
my_map[4] = "student4";//添加元素4
if(my_map.find(4) != my_map.end())
cout << "有4这个元素" << endl;
if(my_map.count(4))
cout << "有4这个元素" << endl;
return 0;
}
9.map在题目中有3个应用:
a.去重:利用映射的一一对应性,把可能出现重复的数据设置为key以达到去重的目的。
b.排序:主要是按照key排序,map是STL的一个模版类,以下是map的定义:
template<class Key,class T,class Compare =less<Key>,
class Allocator = allocator<pair<const Key,T>>>class map;
//其实map<>里面应该有三个变量,而第三个变量是排序方式,
//如果我们不指定排序方式的话,按照平时的写法,map就会按照模版中的less<Key>进行排列
那class Compare = less< Key>的类模版是什么呢?
template<class T>struct greater :binary_function<T,T,bool>
{
bool operator()(const T& x,const T&y)const
{return x > y;}
}
//map默认按字典序排序
如果我们想按照自己的要求进行map排序应该怎么做呢?
我们可以自己定义一个Compare类,把这个类按照map的模版,加在本该在Compare类的位置上,就可以自定义key的排序方式了。
比如我建了一个学生-成绩的map,原先是按照学生姓名的字典序排序的,如果我想按照降序呢?学生姓名长度呢?
//按照默认cmp的输出
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string,int> my_map;
map<string,int> ::iterator iter;
my_map.insert(make_pair("CCCC", 100));
my_map.insert(make_pair("BB", 68));
my_map.insert(make_pair("AAA", 99));
for(iter = my_map.begin();iter != my_map.end();iter++)
cout << iter ->first << " " << iter -> second << endl;
return 0;
}
/*
输出结果:
AAA 99
BB 68
CCCC 100
*/
//降序输出
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string,int,greater<string>> my_map;
map<string,int> ::iterator iter;
my_map.insert(make_pair("CCCC", 100));
my_map.insert(make_pair("BB", 68));
my_map.insert(make_pair("AAA", 99));
for(iter = my_map.begin();iter != my_map.end();iter++)
cout << iter ->first << " " << iter -> second << endl;
return 0;
}
/*
输出结果:
CCCC 100
BB 68
AAA 99
*/
//自定义cmp按照长度升序输出
#include<iostream>
#include<map>
#include<string>
using namespace std;
struct cmp
{
bool operator()(string a,string b)
{
return a.length() < b.length();
}
};
int main()
{
map<string,int,cmp> my_map;
map<string,int> ::iterator iter;
my_map.insert(make_pair("CCCC", 100));
my_map.insert(make_pair("BB", 68));
my_map.insert(make_pair("AAA", 99));
for(iter = my_map.begin();iter != my_map.end();iter++)
cout << iter ->first << " " << iter -> second << endl;
return 0;
}
/*
输出结果:
BB 68
AAA 99
CCCC 100
*/
c.计数:假设定义一个map< string,int>map,输入数据s,记为first,map[s]++;
10.什么样的题目适合使用map呢?
去重计数类问题
可以打乱重新排序的问
题有清晰的一对一的问题
例题:
map例题之未检录人数