C++ STL map(映射)

本文深入解析C++ STL中的map容器,介绍其基本概念、常用操作及应用场景,特别是作为Hash表的使用方法,以及如何利用map进行字符串出现次数的统计。

头文件#include<map>,当然,万能库就不用我多说了吧。。

介绍:map容器是一个键 (key) 到值 (value) 的映射。因为重载了 [ ] 运算符,map像是数组的“高级版”。map的key和value可以是任意类型,其中key必须定义“小于号”运算符。例如可以用一个map <string,int> month_name 来表示“月份名字到月份编号”的映射,然后用month_name["July"]=7;这样的方式来赋值。

声明

map<key_type,value_type>name;

例如:

map<long long,bool>vis;
map<string,int>hash;
map<pair<int,int>,vector<int>>test;

在很多时候,map容器被当作Hash表使用,建立从复杂信息key(如字符串)到简单信息 value(如一定范围内的整数)的映射。
因为map基于平衡树实现,所以它的大部分操作的时间复杂度都在\(O(log n)\)级别,略慢于使用 Hash函数实现的传统Hash表。从C++11开始,STL中新增了 unordered_map 等基于Hash的容器,但部分算法竞赛并不支持C++11标准,这里就不再介绍这些新容器。

size/empty/clear/begin/end
与set类似,分别为元素个数、是否为空、清空、首迭代器、尾迭代器。

迭代器
map 的迭代器和 set 一样,也是“双向访问迭代器”。对 map 的迭代器解除引用后,将得到一个二元组 pair<key_type,value_type>

insert/erase
与set类似,分别为插入、删除。insert的参数是pair<key_type,value_type> ,erase的参数可以是pair或者迭代器。

map<int,int > h;
h.insert(make_pair(1,2)),h.insert(make_pair(2,3));
map<int,int > :: iterator it=h.begin();
pair<int,int > p=*it;
h.erase(it),h.erase(make_pair(2,3));
cout<<p.first<<' '<<p.second<<endl;

find
h.find(x) 在变量名为h 的map 中查找key 为 x 的二元组,并返回指向改二元组的迭代器。若不存在,返回h.end()。时间复杂度为 \(O(log n)\)

[ ] 操作符
h[key]返回key映射到的value的引用,时间复杂度为\(O(log n)\)
[ ]操作符是map最吸引人的地方。我们可以很方便地通过 h[key] 来得到 key 对应的value,还可以对 h[key] 进行赋值操作,改变key对应的value。
需要特别注意的是,若查找的key不存在,则执行 h[key] 后,h会自动新建一个二元组(key,zero),并返回zero的引用。这里zero表示一个广义“零值”,如整数0、空字符串等。如果查找后不对 h[key] 进行赋值,那么时间一长,h 会包含很多无用的“零值二元组”,白白地占用了空间,降低了程序运行效率。强烈建议读者在用 [ ] 操作符查询之前,先用 find 方法检查 key 的存在性。

[实例] 用map统计字符串出现的次数
给定 n 个字符串,m 个问题,每个问题询问一个字符串出现的次数。
n<=20000,m<=20000,每个字符串的长度都不超过20.

map<string,int> h;
char str[25];
for(int i=1;i<=n;i++){
    scanf("%s",str);
    h[str]++;
}
for(int i=1;i<=m;i++){
    scanf("%s",str);
    if(h.find(str)==h.end())puts("0");
    else printf("%d\n",h[str]);
}

提示
set头文件中的set和map头文件中的map分别是集合和映射。二者都支持insert、find、count和remove操作,并且可以按照从小到大的顺序循环遍历其中的元素。map还提供了“[ ]”运算符,使得 map 可以像数组一样使用。事实上,map 也称为“关联数组”。

转载于:https://www.cnblogs.com/Luvwgyx/p/8456320.html

### C++ STL 中 `map` 容器的使用方法 #### 创建 `map` `std::map` 是关联容器,存储由唯一键及其对应的映射值组成的元素对。默认情况下,`map` 的键会自动按升序排列。 ```cpp #include <iostream> #include <map> using namespace std; int main() { // 创建一个字符串到整数的映射 map<string, int> studentScores; } ``` #### 插入元素 可以通过多种方式向 `map` 中插入新元素: - **直接赋值** ```cpp studentScores["Alice"] = 85; // 插入键 "Alice" 和其对应分数 85 ``` - **使用成员函数 insert** ```cpp studentScores.insert(make_pair("Bob", 92)); // 插入键 "Bob" 及其成绩 92 ``` 以上两种方法均能实现相同效果[^1]。 #### 查找元素 要访问已存在的条目,可利用下标运算符或 find 函数来定位特定项: - 下标运算 如果指定的 key 存在于 container,则返回该位置上的 value;如果不存在则会在内部创建一个新的 entry 并初始化为零(对于内置数值类型),这可能不是预期行为,在不确定的情况下应优先考虑使用 `find()` 方法代替[]操作符。 ```cpp cout << "Score of Alice is " << studentScores["Alice"]; // 输出: Score of Alice is 85 ``` - 成员函数 find() 返回指向找到项目的迭代器,如果没有匹配项目则返回 end(). ```cpp auto it = studentScores.find("Charlie"); if (it != studentScores.end()) { cout << "Found Charlie with score " << (*it).second; } ``` #### 遍历 `map` 遍历整个集合可以采用基于范围的循环语法或是传统的迭代器模式: - 基于范围的for语句 ```cpp for(const auto& pair : studentScores){ cout<<pair.first<<" has a score "<<pair.second<<"\n"; } ``` - 使用迭代器 ```cpp for(auto itr = studentScores.begin();itr!=studentScores.end();++itr){ cout<<(*itr).first<<" got marks "<<(*itr).second<<"\n"; } ``` 这两种形式都可以有效地枚举所有的键值对[^3]. #### 删除元素 当不再需要某些记录时,可以从 `map` 移除它们: - erase(key) 根据给定的关键字移除单个项目。 ```cpp studentScores.erase("David"); // 将删除 David 记录 ``` - clear() 清空所有数据。 ```cpp studentScores.clear(); ``` 上述就是关于 C++ Standard Template Library (`STL`) 中 `map` 类型的主要功能概述及简单实例说明.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值