任务描述
本关任务:仔细阅读下文键值对映射map
的相关操作,并使用map
记录学生姓名和成绩,完成对N
个学生信息的插入、删除和查询等功能。
相关知识
为了完成本关任务,你需要掌握:1.键值对映射的概念;2.插入元素;3.删除元素;4.查询关键字;5.遍历键值对映射;6.清空键值对映射。
键值对映射的概念
键值对映射map
是由键key
和值value
构成的一对单元,其中key
和value
可以是任意的数据类型。map
通过建立一颗红黑树(平衡二叉树)来实现对数据自动排序的功能,从而达到高效查询和检索的目的。
键值对映射map
被包含在map
头文件中,定义方式如下(注意搭配algorithm
和using namespace std
一起使用):
map<int, int> mp1; 定义一个int->int的映射
map<string, int> mp2; 定义一个string->int的映射
// 注意:map支持的字符串为string类型,而不是char*
插入元素
向一个键值对映射插入一个映射单元有两种常用操作,如下实例:
map<char, int> mp; // 创建一个字符char->整形int的映射
// 方式一:利用pair构建一个映射单元,用insert函数插入pair
pair<char, int> p; // or pair<char, int> p('a', 0);
p1.first = 'a';
p1.second = 0;
mp.insert(p);
// 方式二:用数组下标的方式插入数据:
mp['b'] = 0
// 也可以直接使用该方式访问元素
cout<<mp['b'];
删除元素
键值对映射通过erase()
方法来删除元素,一般的有两种常见的调用方式:
// 方式一:通过key键删除,方便实用
mp.erase('a');
// 方式二:通过迭代器指针的方式删除
map<char, int>::iterator it=mp.begin();
mp.erase(it);
查询关键字
在键值对映射中查找一个元素通过find()
方法完成,若存在则返回一个迭代器指向元素所在的位置,否则返回键值对映射的尾地址:
map<char, int>::iterator it = mp.find('a');
if(it==mp.end())cout<<"cannot found";
else cout<<it->first<<" "<<it->second;
// first为键,second为值
遍历键值对映射
键值对映射的遍历可以通过迭代器的方式:
for(map<char, int>::iterator it=mp.begin();it!=mp.end();it++)
cout<<it->first<<" "<<it->second;
清空键值对映射
键值对映射的清空通过调用clear()
方法实现,清空后大小变为0
:
mp.clear()
编程要求
本关的编程任务是补全右侧代码片段main
中Begin
至End
中间的代码,具体要求如下:
- 创建一个空的映射
map: string->int
; - 读取数据:读取和处理数据:插入
N
个学生信息(姓名 成绩); - 读取和处理数据:删除
M
个学生信息(姓名); - 遍历映射
map
; - 查找
Q
个学生信息; - 调用
clear
清空。
测试说明
平台将自动编译补全后的代码,并生成若干组测试数据,接着根据程序的输出判断程序是否正确。
以下是平台的测试样例:
测试输入: 7
insert Helen 88
insert Martin 51
insert James 88
insert Joseph 60
insert Joan 99
insert Lily 91
insert Lily 88
5
erase Helen
erase James
erase Joseph
erase Lily
erase Lily
3
find Martin
find James
find Malcolm
预期输出: Lily has been recorded
Lily has not been recorded
print map: 2
Joan 99
Martin 51
Martin score 51
James cannot been found
Malcolm cannot been found
0
输入格式: 整数N:表示待插入N个学生信息
接下来N行:insert student_name student_score表示插入学生姓名student_name成绩student_score
整数M:表示删除M个学生信息
接下来M行:erase student_name表示删除该学生student_name
整数Q:表示查询Q个学生信息
接下来Q行:find student_name表示查询该学生student_name信息
输出格式: 插入阶段:若待插入学生已经存在map中,那么输出student_name has been recorded
删除阶段:若待删除学生不存在map中,那么输出student_name has not been recorded
遍历输出:目前map中的所有学生和成绩
查询阶段:对每次查询输出学生姓名和成绩,若不在记录中,则输出student_name cannot been found
最后一行:非学员输出,数值0用于检测向量是否清空
//
// main.cpp
// step5
//
// Created by ljpc on 2018/7/25.
// Copyright © 2018年 ljpc. All rights reserved.
//
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <map>
using namespace std;
int main(int argc, const char * argv[]) {
// 请在这里补充代码,完成本关任务
/********* Begin *********/
// 1.创建一个空的键值对映射mp: 键string->值int
map<string, int> mp;
// 2.读取和处理数据:插入n个学生信息(姓名 成绩),并按指定要求输出
int n;
cin >> n;
for (int i = 0; i < n; ++i) {
string op, name;
int score;
cin >> op >> name;
if (op == "insert") {
cin >> score;
if (mp.count(name)) {
cout << name << " has been recorded" << endl;
} else {
mp[name] = score;
}
}
}
// 3.读取和处理数据:删除m个学生信息(姓名),并按指定要求输出
int m;
cin >> m;
for (int i = 0; i < m; ++i) {
string op, name;
cin >> op >> name;
if (op == "erase") {
if (mp.count(name)) {
mp.erase(name);
} else {
cout << name << " has not been recorded" << endl;
}
}
}
// 4.遍历映射mp,并按指定要求输出
cout << "print map: " << mp.size() << endl;
for (auto it = mp.begin(); it != mp.end(); ++it) {
cout << it->first << " " << it->second << endl;
}
// 5.查找q个学生信息,并按指定要求输出
int q;
cin >> q;
for (int i = 0; i < q; ++i) {
string op, name;
cin >> op >> name;
if (op == "find") {
if (mp.count(name)) {
cout << name << " score " << mp[name] << endl;
} else {
cout << name << " cannot been found" << endl;
}
}
}
// 6.清空集合
mp.clear();
/********* End *********/
printf("%d\n", int(mp.size()));
return 0;
}