C++ map遍历,map排序--- PAT B1080 MOOC成绩

3 篇文章 0 订阅

题目链接:https://www.patest.cn/contests/pat-b-practise/1080

在B1044讲过map的简单应用,此题目主要用到了map的遍历、map的排序(可以对Value排序)。

map的key值可以是任意类型,遍历时需要用到迭代器。比如:

map<string,Student> stu; //定义一个map,包含string的学号和Student结构体
map<string,Student>::iterator it; //定义一个同类型的迭代器
    it = stu.begin();
    while(it != stu.end()){ /* 遍历时实现一些需求
        if(it->second.g1>=200){ //it->first表示每个pair的第一个key,it->second表示第二个
            if(it->second.g2>it->second.g3)
                it->second.g = round(it->second.g2 * 0.4 + it->second.g3 * 0.6);
            else it->second.g = it->second.g3;
        } */
        it++;
    }

利用迭代器就能方便实现遍历。

接下来看map的排序,map默认按照key排序,如果想改变其排序方式,或者按照Value排序,则可以考虑将map转化为vector再进行排序

将map转化为vector只需要如下两句:

typedef pair<string, Student> PAIR; //每一个点对pair,类型与map中点对一致
vector<PAIR> vs(stu.begin(), stu.end()); //声明一个vector,将一个map全部转化为vector

对vector排序需要写cmp函数,由于本题需要对pair中第二个类型Student中的平均成绩G进行排序,因此cmp可写成如下:

bool CmpByG(const PAIR& p1, const PAIR& p2) { //vector中对PAIR类型,故传入PAIR,对其第二个类型进行降序排序
    if(p1.second.g > p2.second.g) return true; //p.second表示第二个类型
    if(p1.second.g == p2.second.g){ //第二个相等时,再按照第一个增序排序
        if(p1.first<p2.first) //string类型排序,直接比较
            return true;
        else return false;
    }
    return false;
}

排序时只需要写下如下sort函数,即可实现map的排序:

sort(vs.begin(),vs.end(),CmpByG);

了解了map的排序和遍历后,此题目就很好处理;输入时写入map中,然后对平均值排序即可得到结果。

代码如下:

#include <iostream>
#include <map>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;
struct Student{
    int g1,g2,g3,g;
};
map<string,Student> stu;
typedef pair<string, Student> PAIR;

bool CmpByG(const PAIR& p1, const PAIR& p2) {
    if(p1.second.g > p2.second.g) return true;
    if(p1.second.g == p2.second.g){
        if(p1.first<p2.first)
            return true;
        else return false;
    }
    return false;
}
int main()
{
    int P,M,N;
    string xuehao;
    cin>>P>>M>>N;
    for(int i=0;i<P;i++){
        cin>>xuehao;
        cin>>stu[xuehao].g1;
        stu[xuehao].g2 = stu[xuehao].g3 = stu[xuehao].g = -1;
    }
    for(int i=0;i<M;i++){
        cin>>xuehao;
        cin>>stu[xuehao].g2;
        if(stu[xuehao].g != -1)
            stu[xuehao].g1 = stu[xuehao].g3 =stu[xuehao].g =-1;
    }
    for(int i=0;i<N;i++){
        cin>>xuehao;
        cin>>stu[xuehao].g3;
        if(stu[xuehao].g != -1)
            stu[xuehao].g1 = stu[xuehao].g2 =stu[xuehao].g =-1;
    }
    map<string,Student>::iterator it;
    it = stu.begin();
    while(it != stu.end()){
        if(it->second.g1>=200){
            if(it->second.g2>it->second.g3)
                it->second.g = round(it->second.g2 * 0.4 + it->second.g3 * 0.6);
            else it->second.g = it->second.g3;
        }
        it++;
    }
    vector<PAIR> vs(stu.begin(), stu.end());
    sort(vs.begin(),vs.end(),CmpByG);
    for (int i = 0; i < vs.size(); i++) {
        if(vs[i].second.g>=60)
           cout << vs[i].first<<" "<< vs[i].second.g1 <<" "<< vs[i].second.g2 <<" "<< vs[i].second.g3<<" "<< vs[i].second.g << endl;
    }
    return 0;
}




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值