问题背景

在做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的一个知识点的更多相关文章

  1. STL中map的使用

    知识点 C++中map提供的是一种键值对容器,里面的数据都是成对出现的.map内部自建一颗红黑树(一种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的. ...

  2. C++ STL中Map的按Key排序和按Value排序

    map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定不存在重名,当然可以对重名加以区 分),我们用map来进 ...

  3. STL中map与hash_map的比较

    1. map : C++的STL中map是使用树来做查找算法; 时间复杂度:O(log2N) 2. hash_map : 使用hash表来排列配对,hash表是使用关键字来计算表位置; 时间复杂度:O ...

  4. STL中map与hash_map容器的选择收藏

    这篇文章来自我今天碰到的一个问题,一个朋友问我使用map和hash_map的效率问题,虽然我也了解一些,但是我不敢直接告诉朋友,因为我怕我说错了,通过我查询一些帖子,我这里做一个总结!内容分别来自al ...

  5. C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET

    C++ STL中Map的相关排序操作:按Key排序和按Value排序 - 编程小径 - 博客频道 - CSDN.NET C++ STL中Map的相关排序操作:按Key排序和按Value排序 分类: C ...

  6. C++中的STL中map用法详解(转)

    原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解   Map是STL的一个关联容器,它提供 ...

  7. C++ STL中Map的按Key排序跟按Value排序

    C++ STL中Map的按Key排序和按Value排序 map是用来存放<key, value>键值对的数据结构,可以很方便快速的根据key查到相应的value.假如存储学生和其成绩(假定 ...

  8. C++ STL 中 map 容器

    C++ STL 中 map 容器 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它 ...

  9. stl中map的四种插入方法总结

    stl中map的四种插入方法总结方法一:pair例:map<int, string> mp;mp.insert(pair<int,string>(1,"aaaaa&q ...

随机推荐

  1. 运行出第一个程序Hello World、第二个程序网页浏览器

    很长时间没有发博客记录我的奋斗历程了,原因不外乎遇到了对我而言“巨大的”困难. 经历了长期的找不到合适的教材.找不到Xcode资源.运行不出例程的痛苦以后,近日终于走上正轨. 现在补发一个过去2个月来 ...

  2. .htaccess文件url重写小记

    .htaccess文件url重写 当上一条规则匹配 并转换后 符合下一条规则的 继续下一条的匹配转换 RewriteRule ^shangpin-([0-9a-zA-Z]+)/category-([0 ...

  3. ubuntu 自动获取ip的怎么设置

    ubuntu以DHCP方式配置网卡自动获取ip编辑文件/etc/network/interfaces:sudo vi /etc/network/interfaces并用下面的行来替换有关eth0的行: ...

  4. python--windows下安装BeautifulSoup

    python有很多内置的模块可以不安装使用,用起来非常方便,但是也有一些挺有用的非内置的模块不能直接使用,需要话费点力气手动安装. 进入python安装目录下的Scripts目录,查看是否有pip工具 ...

  5. Oracle10 多行和并

    SELECT fspc, wmsys.wm_concat (jsrzmc) as jsr FROM dxjsrxx GROUP BY fspc select fspc, LISTAGG(jsrzmc, ...

  6. 多说【最近访客】JS插件通用代码使用方法

    多说[最近访客]JS插件可以显示近期访问过你的博客并且已经使用向多说授权过的社交网络账号登录的用户头像,效果如下图所示. 最近访客JS插件的添加步骤如下: 1. 添加多说公用JS代码,每个页面只需添加 ...

  7. ASP.NET网站限制访问频率

    最近做了一个免费发短信的小网站(http://freesms.cloudapp.net/),但发现最近有人破解了我的验证码,以每3秒/条的速度用我的短信服务来发他的广告.更换验证码程序和过滤关键字只是 ...

  8. [转]c++ new带括号和不带括号

    ref:http://m.blog.csdn.net/blog/u012745772/42420443 在new对象的时候有加上(),有不加(),不知道这个到底是什么区别?比如:CBase *base ...

  9. sql查询百分号的方法

    select * from [tablename] where [col] like '%100/%%' escape '/'

  10. Java学习笔记之Scanner报错java.util.NoSuchElementException

    转载自:IT学习者-螃蟹 一个方法A使用了Scanner,在里面把它关闭了.然后又在方法B里调用方法A之后就不能再用Scanner了Scanner in = new Scanner(System.in ...