前言:
map是一种映射,是常用的STL容器。(map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器))
1,map的定义:
map<typename1, typename2>mp;
使用map要确定映射前类型(键key)和映射后的类型(值value)。
2,map容器内元素的访问
(1)通过下标访问
mp<char,int> mp;
mp['c']=20;
mp['b']=30;
cout<<mp['c']; //输出为20
(2)通过迭代器访问
定义方式:
map<typename1, typename2>::iterator it;
map迭代器的使用方式和其他STL容器的迭代器不同,因为map的每一对映射都有两个typename,这决定了必须能通过一个it来同时访问键和值。事实上,map可以使用it->first来访问键,使用it->second来访问值。
3,map常用函数
(1)find()
map中find()函数用于查找指定键是否存在,如果该键存在,find()返回指向该元素的迭代器,如果不存在,则返回map的end()迭代器
find()函数的基本语法:
map<Key, Value>::iterator find(const Key& key);
-
key
:要查找的键。 -
返回值:如果
key
存在,返回指向该元素的迭代器;如果key
不存在,返回map
的end()
迭代器.
示例 1:查找 map
中是否存在某个键
#include <bits/stdc++.h>
using namespace std;
void solve()
{
map<int, string> mp;
mp[1] = "apple";
mp[2] = "banana";
mp[3] = "cherry";
int key = 2; // 要查找的键
auto it = mp.find(key); // 查找键是否存在
if (it != mp.end()) {
// 找到该键,输出对应的值
cout << "找到键 " << key << ",值为:" << it->second << endl;
} else {
// 没找到该键
cout << "没有找到键 " << key << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
找到键 2,值为:banana
示例 2:查找元素并判断其是否存在
#include <bits/stdc++.h>
using namespace std;
void solve()
{
map<string, int> mp;
mp["apple"] = 5;
mp["banana"] = 3;
mp["cherry"] = 8;
string key = "banana";
auto it = mp.find(key); // 查找键是否存在
if (it != mp.end()) {
cout << "找到键 " << key << ",值为:" << it->second << endl;
} else {
cout << "没有找到键 " << key << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
找到键 banana,值为:3
示例 3:处理 find()
查找结果
#include <bits/stdc++.h>
using namespace std;
void solve()
{
map<int, string> mp;
mp[10] = "ten";
mp[20] = "twenty";
mp[30] = "thirty";
// 查找并直接修改值
int key = 20;
auto it = mp.find(key);
if (it != mp.end()) {
// 找到后修改值
it->second = "updated twenty";
cout << "更新后的值:" << it->second << endl;
} else {
cout << "没有找到该键" << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
更新后的值:updated twenty
实例4:map会自动排序
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e6 + 10;
void solve()
{
int n;
cin>>n;
map<int,int> mp;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
mp[x]++;
}
auto mn=*mp.begin();
auto mx=*mp.rbegin();
cout<<mn.first<<' '<<mn.second<<endl;
cout<<mx.first<<' '<<mx.second<<endl;
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T = 1;
while (T--)
{
solve();
}
return 0;
}
查找map的第一值跟最后一个值
auto mn=*mp.begin();
auto mx=*mp.rbegin();
(2)clear()
map
中的 erase()
函数用于从 map
中删除指定的元素。它有几种不同的用法,具体取决于你想删除的内容。erase()
可以通过键、迭代器,或者通过指定范围来删除元素。
erase()
函数的基本用法
示例 1:通过键删除元素
#include <bits/stdc++.h>
using namespace std;
void solve()
{
map<int, string> mp;
mp[1] = "apple";
mp[2] = "banana";
mp[3] = "cherry";
// 删除键为 2 的元素
mp.erase(2);
// 输出剩余的元素
for (const auto& p : mp) {
cout << p.first << " => " << p.second << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
1 => apple
3 => cherry
示例 2:通过迭代器删除元素
#include <bits/stdc++.h>
using namespace std;
void solve()
{
map<int, string> mp;
mp[1] = "apple";
mp[2] = "banana";
mp[3] = "cherry";
// 获取迭代器指向键为 2 的元素
auto it = mp.find(2);
if (it != mp.end()) {
// 通过迭代器删除元素
mp.erase(it);
}
// 输出剩余的元素
for (const auto& p : mp) {
cout << p.first << " => " << p.second << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
1 => apple
3 => cherry
示例 3:通过迭代器范围删除元素
#include <bits/stdc++.h>
using namespace std;
void solve()
{
map<int, string> mp;
mp[1] = "apple";
mp[2] = "banana";
mp[3] = "cherry";
mp[4] = "date";
mp[5] = "elderberry";
// 获取迭代器指向删除区间
auto first = mp.find(2);
auto last = mp.find(5); // 注意,last 指向的是范围外的元素
// 删除键为 2 到 4 的元素
mp.erase(first, last);
// 输出剩余的元素
for (const auto& p : mp) {
cout << p.first << " => " << p.second << endl;
}
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
(3)size()
size()用来获得map中映射的对数,时间复杂度为O(1)。
(4)clear()
clear()用来清空map中的所有元素,复杂度为O(N),其中N为map中的元素的个数。
4.map的常见用途:
1. 统计数据
map
常常用于统计数据,尤其是需要根据某个键(如单词、ID、时间等)存储和检索对应的数据(如频率、数量、值等)的场景。- 例子:统计一篇文章中每个单词出现的次数。
#include <bits/stdc++.h>
using namespace std;
void solve() {
string text = "hello world hello map";
map<string, int> word_count;
stringstream ss(text);
string word;
while (ss >> word) {
word_count[word]++;
}
for (const auto& p : word_count) {
cout << p.first << ": " << p.second << endl;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
hello: 2
map: 1
world: 1
2. 存储键值对(键唯一)
map
适用于需要存储键值对的数据结构,并且要求每个键是唯一的。例如,可以用map
来存储学生的学号和姓名、产品的ID和价格等。- 例子:用
map
存储和查找学生的学号和姓名。
#include <bits/stdc++.h>
using namespace std;
void solve() {
map<int, string> students;
students[101] = "Alice";
students[102] = "Bob";
students[103] = "Charlie";
// 查找学号 102 的学生姓名
cout << "Student with ID 102: " << students[102] << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
Student with ID 102: Bob
3. 排序数据
- 由于
map
内部是按照键的顺序存储的(默认情况下按升序排序),因此当需要在存储数据的同时保持数据的有序性时,map
是一个理想的选择。 - 例子:存储一组数字并保持其有序性。
#include <bits/stdc++.h>
using namespace std;
void solve() {
map<int, string> mp;
mp[3] = "apple";
mp[1] = "banana";
mp[2] = "cherry";
// 输出按键升序排序的元素
for (const auto& p : mp) {
cout << p.first << " => " << p.second << endl;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
4. 实现缓存或查找表(Memoization)
- 在算法中,尤其是动态规划和递归问题中,
map
可以用于缓存已经计算过的结果(记忆化搜索)。这样可以避免重复计算,提高效率。 - 例子:用
map
实现斐波那契数列的记忆化递归。
#include <bits/stdc++.h>
using namespace std;
map<int, int> memo;
int fibonacci(int n) {
if (n <= 1) return n;
if (memo.find(n) != memo.end()) return memo[n]; // 查找缓存
return memo[n] = fibonacci(n - 1) + fibonacci(n - 2); // 计算并缓存
}
void solve() {
int n = 10;
cout << "Fibonacci of " << n << " is: " << fibonacci(n) << endl;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
Fibonacci of 10 is: 55
5. 区间查找与范围查询
map
的元素是有序的,支持区间查找和范围查询操作。例如,可以通过lower_bound()
和upper_bound()
查找某个键的范围。- 例子:查找所有大于等于某个键的元素。
#include <bits/stdc++.h>
using namespace std;
void solve() {
map<int, string> mp;
mp[1] = "apple";
mp[2] = "banana";
mp[3] = "cherry";
mp[4] = "date";
mp[5] = "elderberry";
auto it = mp.lower_bound(3); // 查找大于等于 3 的第一个元素
while (it != mp.end()) {
cout << it->first << " => " << it->second << endl;
++it;
}
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}
输出
3 => cherry
4 => date
5 => elderberry
总结
map
常用于以下几种场景:
- 统计数据(如单词频率、计数等)。
- 存储键值对并保持键唯一。
- 在需要排序的情况下存储数据。
- 实现缓存、查找表(如记忆化搜索)。
- 频繁进行查找、更新操作。
- 区间查找和范围查询。
由于 map
提供了高效的查找、插入和删除操作,适用于各种需要快速存取、排序和更新的数据处理任务。