总结
1)map就是一个类型到另一个类型的映射,打破数组常规。
2)需要建立字符(或字符串)与整数(or其他类型)第一个想到就是用map建立映射
3)判断大整数或者其他类型的数据是否存在的题目,可以吧map当做bool数组用
4)字符串到字符串的映射
5)访问的两种方式
- 数组
- 迭代器 it->first, it->second
6)4个函数
- find()
- erase()
- size()
- clear()
延伸:map的建和值的是唯一的,如果一个键需要对应多个值,就只能用multimap。下去可以学学 unordered_map。以散列代替map内部的红黑树实现,其用来处理只映射而不按key排序 的需求, 比map快的多
什么是map?
map的中问翻译为映射,很常用,之前我一直不会,今天一定要学会,
As we all know,定义数组时,如 int array[100],其实就是定义了一个从int 到int 的映射, 比如array[0] = 25,就是将0 映射到 25,一个double 型的数组,则是将int 型映射到double型,无论是什么类型他总是将int型映射到其他类型,这样就出现了弊端。当我们需要以其他类型作为关键字来做映射时,会显得很不方便,像我们的字典,不都是提供可很多字符,然后让你找页码么,这个映射就是 “字符串 --》页码 ”,这样在你没有学map之前,就很难操作了,但是今天你要学map了,这就不在是个问题了。
因为map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器)也就是可以建立string型到int 型的映射
map的基本应用
1)定义
当然STL容器你用谁就要有谁的头文件
#include<map>
using namespace std;
让我们先来定一个map练练手
map<typename1, typename2> mp;
map和其他STL容器在定义上有点不一样,因为map需要确定映射前的类型(键key)和映射后的类型(值value)所以我们需要在 < > 内填写两个类型,其中第一个是键的类型,第二个是值的类型,如果是int 映射到 int 就是普通的int 型数组。
若果是字符串映射到其他类型必须是 string 而不能用char
map<stirng, int> mp;
map的键和值也可以用STL容器
map<set<int>, string> mp;
2)访问map容器中的元素
(1)通过下标访问
和普通数组一样,例
map<char, int> mp;
mp['c']; //直接可用 mp['c'] 来访问它对应的整数
于是当建立映射时,就可以直接使用mp['c'] = 20,和普通数组的使用方法一样,但是注意,map中键值唯一,
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30; //直接可用 mp['c'] 来访问它对应的整数
mp['c'] = 20; //30被覆盖
cout << mp['c'] << endl;
return 0;
}
(2)使用迭代器访问
map的迭代器的定义和其他STL容器迭代器定义的方式相同。
map<typename1, typename2>::iterator it;
但是使用方式给其他容器不太一样,因为map的每一对映射都有两个typename,这就决定了,必须能通过其中一个it来同时访问键和值。 事实上可以使用 it->first访问键,it->second访问值
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
printf("%c %d\n", it->first, it->second);
}
return 0;
}
3)常见函数
(1)find()
find(key) 返回key的映射的迭代器,时间复杂度O(logN)N为map中映射的个数
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
map<char, int>::iterator it = mp.find('r');
printf("%c %d\n", it->first, it->second);
return 0;
}
2)erase()
(1)删除单个元素
- mp.erase(it),it为需要删除元素的迭代器,时间复杂度O(1)
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
map<char, int>::iterator it = mp.find('r');
mp.erase(it);
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
printf("%c %d\n", it->first, it->second);
}
return 0;
}
- mp.erase(key),key为与删除映射的键,时间复杂度O(logN)N为map内元素的个数
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
mp.erase('t');
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
printf("%c %d\n", it->first, it->second);
}
return 0;
}
(2)删除一个区间内的所有元素
mp.erase(first, last)其中first为需要删除的区间的起始迭代器,而last则为需要删除的区间的末尾迭代器的下一个地址(好像这些个容器都这样),删除区间也为 [ first, last)时间复杂度O(last - first)。
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
map<char, int>::iterator it = mp.find('r');
mp.erase(it, mp.end());
for(map<char, int>::iterator it = mp.begin(); it != mp.end(); it++){
printf("%c %d\n", it->first, it->second);
}
return 0;
}
3)size()
输出映射对数
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
cout << mp.size() << endl;
return 0;
}
4)clear()
清空map内所有元素时间复杂度为O(N)
#include<iostream>
#include<stdio.h>
#include<map>
using namespace std;
int main(){
map<char, int> mp;
mp['c'] = 30;
mp['r'] = 20;
mp['t'] = 50;
mp.clear();
cout << mp.size() << endl;
return 0;
}
例题:
#include<iostream>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<stdio.h>
#include<map>
using namespace std;
typedef long long ll;
map<long, bool> mp;
int main (){
long long n;
cin >> n;
mp[n] = 1;
n++;
while(n%10 == 0){
n/=10;
}
long long ans = 0;
while(1){
if(mp[n] == 1){
ans++;
break;
}
mp[n] = 1;
n++;
while(n%10 == 0){
n/=10;
}
ans++;
}
cout << ans << endl;
return 0;
}