使用C ++ / STL找出每门学科中得分最低的学生

时间:2019-07-16 15:06:07

标签: c++ c++11 stl

每个学生在不同的科目中获得满分(满分10分)。以下是带有学生名,主题,标记的示例csv文件。

我们如何使用适当的数据结构编写高效的程序来解析此文件,对其进行处理并生成输出?我们的输出应该打印出得分(和主题)得分最低的人。

john, maths, 8
roy, science, 6
john, science, 5
sara, arts, 7
neil, maths, 4
tony, arts, 6
bob, science, 7
tony, maths, 7
neil, science, 8
john, arts, 4
sara, history, 3

我们的输出应打印谁得分最低的主题(与该主题的所有其他主题相比)。所以我们的输出应该是:

neil
john

由于尼尔在数学上的得分最低,约翰在科学和艺术上的得分最低。 (但是,sara不会出现在输出中,因为sara在历史上的得分没有低于该主题的任何人)

我做了什么?

我尝试以这种方式使用两个地图:<subject, <name, marks>>

std::unordered_map<std::string, std::unordered_map<std::string, int>> name_subject_marks;

在这里,我将针对每个主题添加<name, marks>。而且,如果该主题已经存在,则仅当现有分数更高时,我才替换关联的<name, marks>。因此,最后我将获得该主题分数最低的名称。

但是,sara也出现在此列表中。我该如何处理?另外,请告诉我是否有更好的方法。

1 个答案:

答案 0 :(得分:1)

使用布尔标志标记每个主题的第一人称。遍历每行。分割线。将标记和带有标记的名称存储在地图中。遍历地图以在集合中插入所有名称。遍历集合以打印名称。

#include <iostream>
#include <unordered_map>
#include <set>
#include <sstream>

int main() {
    std::string filename;
    std::cin >> filename;
    std::ifstream file(filename);
    std::unordered_map<std::string, std::tuple<unsigned short, std::string, bool>> lowestMarks;
    std::string line;
    while (std::getline(file, line)) {
        std::stringstream sline(line);
        std::string name;
        std::string subject;
        unsigned short mark;
        std::getline(sline, name, ',');
        std::getline(sline, subject, ' ');
        std::getline(sline, subject, ',');
        sline >> mark;
        auto lowestMark = lowestMarks.find(subject);
        if (lowestMark == lowestMarks.end()) {
            lowestMarks[subject] = std::make_tuple(mark, name, true);
        } else if (std::get<0>(lowestMark->second) > mark) {
            lowestMarks[subject] = std::make_tuple(mark, name, false);
        } else {
            std::get<2>(lowestMarks[subject]) = false;
        }
    }
    std::set<std::string> names;
    for (auto lm : lowestMarks) {
        if (std::get<2>(lm.second)) continue;
        names.insert(std::get<1>(lm.second));
    }
    for (auto name : names) {
        std::cout << name << '\n';
    }
    return 0;
}

该代码已使用clang ++ -std=c++11进行了测试。输出是

john
neil