STL课程
第九课:《智能电话本——认识Map(映射)》
本课目标
理解什么是 Map(映射)。
理解"键(Key)"和"值(Value)"的概念。
掌握
[]、insert()、find()、count()、erase()、size()、empty()的使用。能利用 Map 建立"对应关系"。
能利用 Map 完成简单统计。
第一幕 神奇电话本
今天。
程序王国来了一个新的管理员。
他说:
我有一本神奇电话本。
里面记录着:
小明 → 13888888888 小红 → 13999999999 小刚 → 13666666666如果我知道:
小明
能不能立刻找到:
电话号码?
今天我们认识的新朋友。
叫:
Map
中文名字:
映射
或者:
键值对容器
它最大的本领就是:
一个东西,对应另一个东西。
第二幕 什么叫"映射"?
画图:
姓名 小明 ─────────► 13888888888 小红 ─────────► 13999999999 小刚 ─────────► 13666666666左边。
叫:
Key(键)
右边。
叫:
Value(值)
一句口诀:
通过Key,找到Value。
第三幕 Map还能保存什么?
继续画图。
不仅:
姓名。
还能:
国家。
China ↓ 广州 USA ↓ 纽约还能:
动物。
Cat ↓ 猫 Dog ↓ 狗还能:
学号。
1001 ↓ 张三Map就是:
建立对应关系。
第四幕 请出Map
头文件:
#include<iostream> #include<map> using namespace std;创建:
map<string,string> phone;解释:
前面的:
string表示:
姓名。
后面的:
string表示:
电话号码。
提醒:
Map要写两个类型。
左边。
右边。
可以分别设定。
第五幕 添加电话
最简单的方法:
phone["小明"]="13888888888"; phone["小红"]="13999999999"; phone["小刚"]="13666666666";画图:
小明 ↓ 13888888888第六幕 查电话
请问:
小明电话多少?
程序:
cout<<phone["小明"];输出:
13888888888是不是很方便?
第七幕 修改电话
如果:
小明换号码了。
程序:
phone["小明"]="18888888888";再输出:
cout<<phone["小明"];结果:
18888888888总结:
再次赋值,就是修改。
第八幕 Map还能统计次数
今天拿了:
苹果 香蕉 苹果 苹果 香蕉请问:
苹果拿了几次?
以前。
需要:
循环统计。
今天使用,
Map。
一句话。
map<string,int> cnt;每来一个水果。
cnt[name]++;结束以后。
cout<<cnt["苹果"];输出:
3同学们惊呼:
这么简单!
第九幕 为什么能++?
解释。
开始,
Map里面没有:
苹果。
程序自动设置:
苹果 ↓ 0然后拿了苹果就:
++变成:
1以后:
再来。
继续:
2 3 4Map非常聪明。
不存在。
就自动创建。
初始值是:
0。(因为设置的是 int 型)
第十幕 遍历Map
Map里面不是:
一个数字。
而是:
很多:
Key。
Value。
详细介绍:
for(auto x:phone) { cout<<x.first<<" "; cout<<x.second<<endl; }解释:
first就是:
左边。
Key。
second就是:
右边。
Value。
例如:
输出:
小刚 13666666666 小明 18888888888 小红 13999999999还有特别棒的是:
Map 会按照 Key 自动排序。
第十一幕 find()
如果问:
有没有:
小明?
程序:
if(phone.find("小明")!=phone.end()) { cout<<"找到"; }map
和Set一样。
找不到。
返回:
end()第十二幕 erase()
删除:
phone.erase("小红");以后。
电话本。
就没有:
小红了。
第十三幕 count()
请问:
有没有:
小刚?
cout<<phone.count("小刚");输出:
1如果:
没有。
输出:
0第十四幕 演示程序
#include<iostream> #include<map> using namespace std; int main() { map<string,string> phone; phone["小明"]="13888888888"; phone["小红"]="13999999999"; phone["小刚"]="13666666666"; cout<<"小明电话:"; cout<<phone["小明"]<<endl; cout<<endl; for(auto x:phone) { cout<<x.first<<" "; cout<<x.second<<endl; } return 0; }第十五幕 课堂实践一——统计单词出现次数
输入:
apple banana apple orange apple banana要求:
输出:
apple 3 banana 2 orange 1参考程序:
#include<iostream> #include<map> using namespace std; int main() { map<string,int> cnt; int n; cin>>n; while(n--) { string s; cin>>s; cnt[s]++; } for(auto x:cnt) { cout<<x.first<<" "<<x.second<<endl; } return 0; }这是:
Map最经典的用途。
第十六幕 课堂实践二——学生成绩查询
输入:
Tom 98 Lucy 100 Jack 95然后输入:
Lucy输出:
100是不是马上会想到刚学的电话本?
第十七幕 Set 和 Map 有什么区别?
画图。
Set:
苹果 香蕉 西瓜只有:
一个东西。
Map:
苹果 ↓ 5元 香蕉 ↓ 3元 西瓜 ↓ 12元总结:
Set只有Key。
Map有Key和Value。
本课总结
今天,我们认识了Map(映射)。
它最大的特点就是:
一个Key,对应一个Value。
我们掌握了七个最常用的成员函数:
| 成员函数 | 作用 | 生活中的理解 |
|---|---|---|
m[key] | 添加、修改、查询 | 根据名字查电话 |
insert() | 插入一组键值对 | 新增联系人 |
find() | 查找Key | 找联系人 |
count() | 判断Key是否存在 | 是否有这个联系人 |
erase() | 删除Key | 删除联系人 |
size() | 元素个数 | 电话本里有多少联系人 |
empty() | 是否为空 | 电话本是不是空的 |
🌟 一定要讲的知识——[]与find()的区别
这是很多同学最容易踩坑的地方。
现场演示:
map<string,int> cnt; cout<<cnt["apple"]<<endl;输出:
0再问:
Map里面原来有apple吗?
没有!
但是执行这一句后:
cnt["apple"]Map 会自动创建:
apple ↓ 0所以:
m[key]不仅可以查询。
还可能:
自动新增元素。
而:
find()只是查找。
不会增加任何东西。
一句话口诀:
[]会"顺手建档案",find()只负责"找档案"。
🌟 竞赛思维
以后。
很多信奥赛题都会使用:
map<int,int> cnt;或者:
map<string,int> cnt;看到:
cnt[x]++;就应该立刻想到:
这是在统计出现次数!
这是Map 在 GESP、CSP-J、NOIP 中出现频率最高的用法之一。