STL中map的一个知识点
问题背景
在做USACO Section 1.1 Greedy Gift Givers的时候,我最初的想法是直接用一个map来进行数据处理。但是后来产生一个让我感到疑问的地方,后来我经过测试,发现了这个被我遗忘的一个知识点,可能对于大家来说这个小知识点算是一个“常识”,但是我却没有想到,所以刻意将它记录下来加深自己的印象。
场景回顾
下面我用一个问题来重现自己的这个问题。
问题描述
在一个班级里面有N个人,他们的学号是按照他们入学报道的顺序确定的,在报道的时候确定学生的id。现在班主任想重新编排一下学号,将原来的学号逆序,也就是说之前的第一个学号现在变成最后一个学号,最后一个学号的学生现在改为第一个学号。班主任更改的方式的通过输入学生的姓名来重新改变学生的学号。
样例输入
3
aaa
bbb
ccc
aaa 2
bbb 1
ccc 0
样例输出
aaa 2
bbb 1
ccc 0
解题思路
用map进行映射,保存数据进行处理。当班主任输入姓名时,可以由map快速查找到该学生,从而改变其学号。这个方法显得有点多此一举,这是为了重现这个问题XD
解题代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int maxn = 10;
struct Person {
string name;
int id;
}p[maxn];
map<string, Person>mp;
int n;
int main() {
scanf("%d", &n);
string str;
for(int i = 0; i < n; i++) {
cin >> str;
p[i].name = str;
p[i].id = i;
mp[str] = p[i];
}
//将学号重新编排
int num;
for(int i = 0; i < n; i++) {
cin >> str >> num;
mp[str].id = num;
}
for(int i = 0; i < n; i++) {
cout << p[i].name << " " << p[i].id << endl;
}
return 0;
}
代码出错
当我将上面的代码运行之后,输入样例,发现输出是这样的:
aaa 0
bbb 1
ccc 2
为什么我明明在上述代码的注释部分进行了学号重新编排,但是最后输出却还是原来的状态呢?
后来我经过下面的代码测试才弄明白我的问题出在哪里:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int maxn = 10;
struct Person {
string name;
int id;
}p[maxn];
map<string, Person>mp;
int n;
int main() {
scanf("%d", &n);
string str;
for(int i = 0; i < n; i++) {
cin >> str;
p[i].name = str;
p[i].id = i;
mp[str] = p[i];
}
//将学号重新编排
int num;
for(int i = 0; i < n; i++) {
cin >> str >> num;
mp[str].id = num;
}
//测试输出
for(int i = 0; i < n; i++) {
cout << p[i].name << " " << p[i].id << endl;
}
cout << "================" << endl;
for(map<string, Person>::iterator it = mp.begin(); it != mp.end(); it++) {
cout << it->second.name << " " << it->second.id << endl;
}
return 0;
}
上面的代码输出如下:
aaa 0
bbb 1
ccc 2
================
aaa 2
bbb 1
ccc 0
找出问题
通过对比输出,我发现其实将p数组放入map中,只是将p数组的拷贝放入了map中,我在map中一切操作都是对这份拷贝进行的。所以最后我输出p数组的内容时是跟初始状态一样的,根本没有任何改变,因为真正的改变是在map中的那份拷贝之中。
如果我想用这个思路解决这个问题,那么我最好换一种解决方式,通过map获得p数组中元素的索引,而不是直接通过map进行更改。
代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
const int maxn = 10;
struct Person {
string name;
int id;
}p[maxn];
map<string, int>mp;
int n;
int main() {
scanf("%d", &n);
string str;
for(int i = 0; i < n; i++) {
cin >> str;
p[i].name = str;
p[i].id = i;
mp[str] = i;
}
int num;
for(int i = 0; i < n; i++) {
cin >> str >> num;
p[mp[str]].id = num;
}
for(int i = 0; i < n; i++) {
cout << p[i].name << " " << p[i].id << endl;
}
return 0;
}
STL中map的一个知识点的更多相关文章
- STL中map的使用
知识点 C++中map提供的是一种键值对容器,里面的数据都是成对出现的.map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的. ...
- C++ STL中Map的按Key排序和按Value排序
map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...
- STL中map与hash_map的比较
1. map : C++的STL中map是使用树来做查找算法; 时间复杂度:O(log2N) 2. hash_map : 使用hash表来排列配对,hash表是使用关键字来计算表位置; 时间复杂度:O ...
- STL中map与hash_map容器的选择收藏
这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自al ...
- C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET
C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
- C++ STL中Map的按Key排序跟按Value排序
C++ STL中Map的按Key排序和按Value排序 map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定 ...
- C++ STL 中 map 容器
C++ STL 中 map 容器 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它 ...
- stl中map的四种插入方法总结
stl中map的四种插入方法总结方法一:pair例:map<int, string> mp;mp.insert(pair<int,string>(1,"aaaaa&q ...
随机推荐
- 动软数据库文档生成器 失败错误码HRESULT:0x80010105 解决办法
是否在关闭office文档模板时提示拼写错误语法检查太多而导致失败?如果是提示这个错误的话,可以将拼写检查和语法检查关掉即可.下附相关链接:http://support.microsoft.com/k ...
- nginx优化缓冲缓存
反向代理的一个问题是代理大量用户时会增加服务器进程的性能冲击影响.在大多数情况下,可以很大程度上能通过利用Nginx的缓冲和缓存功能减轻. 当代理到另一台服务器,两个不同的连接速度会影响客户的体验: ...
- java 静态方法和单例模式的区别
1.加载时间 首先明白内存问题 Java内存分为:堆内存.栈内存.方法区(静态区和非静态区).本地方法区 无论是静态方法还是非静态方法,在内存中都只有一份分别位于方法区的静态区和非静态区:非静态方法在 ...
- asp中的动态数组
<% Dim array1(),i ReDim array1(3)array1(3)=10response.Write(array1(3)&"<br>") ...
- php的错误和异常处理
php中try catch的例子: <?php try { if (@mysql_connect('localhost','root','123456')){ // echo 'success! ...
- get 和 post请求的区别
(1)GET请求用于获取信息,从Client的角度看,不会改变资源状态,并且多次对同一URL的多个请求应该返回相同的结果. GET请求的参数会显示在URL中,即放置在HTTP协议头中(所 ...
- C++左值
C++左值 左值参数是可被引用的数据对象.比如,变量,数组元素,结构成员,引用和解引用指针 非左值包含字面常量(用引号括起的字符串除外,它们是由地址表示的)和包含多项的表达式 在C语言里面左值最初指的 ...
- 包(package)
防止文件重名,包体现在文件夹上.包必须建立文件夹. 类名的全称是:包名.类名 javac xx.java 命令编译的时候,不会建立对应的文件夹, 建立包对应的文件夹的命令,要用 javac -d ...
- python 压缩 解压缩 文件
1. 用zipfile模块打包文件或是目录.解压zip文件 http://wangwei007.blog.51cto.com/68019/1045577 #!/usr/bin/env python # ...
- CentOS安装VirtualBox增强工具
安装过程中出现错误: Bulding the VirtualBox Guest Additions Kernel modules failedYour system does not seem to ...