背景
最近在业务开发的过程中,遇到对unordered_map排序的问题,并且map中的元素类型较为复杂。将具体的业务问题,抽象为如下较易理解的问题。
问题
在若干名学生中,挑选出2名学生。挑选依据:根据学生所有课程中,得分最高的3门成绩,取3门成绩求和最高的2名学生。
std::unordered_map<std::string, std::vector<double>> student_map
表示包含若干名学生的集合,元素包括string类型的学生姓名和一个包含各门课程成绩的vector。
要求返回的结果同样为std::unordered_map<std::string, std::vector<double>> student_map
,但其中只包含符合条件的2名学生。
//挑选两名学生。依据:所有课程中得分最高的3门成绩之和。
//student_map为原始学生集合,要求处理完之后,集合中只存在选出的两名学生。
#include <iostream>
#include "vector"
#include "unordered_map"
struct CompareWithScoreDesc1 {
bool operator()(const double &arg1, const double &arg2) {
return arg1 > arg2;
}
};
double scoreSum(std::vector<double> vec) {
sort(vec.begin(), vec.end(), CompareWithScoreDesc1()); // 对所有课程成绩进行倒序排序
int32_t itemNum = std::min(3, (int32_t) vec.size()); //取得分最高的3门课程成绩求和
double scoreSum = 0;
for (int32_t j = 0; j < itemNum; j++) {
scoreSum = vec[j] + scoreSum;
}
return scoreSum;
}
struct CompareWithScoreDesc2 {
bool operator()(const std::pair<std::string, std::vector<double>> &arg1, const std::pair<std::string, std::vector<double>> &arg2){
return scoreSum(arg1.second) > scoreSum(arg2.second);
}
};
int main() {
// 筛选逻辑
std::unordered_map<std::string, std::vector<double>> student_map; //学生集合,<student_name,<score1,score2,...>>
double stu1[10] = {8119,95,100,86,97,78,90,82,91,88};
if (student_map.find("stu1") == student_map.end()) {
std::vector<double > *vec = new std::vector<double>();
for (int i = 0; i < sizeof(stu1)/ sizeof(stu1[0]); i++) {
vec->push_back(stu1[i]);
}
student_map["stu1"] = *vec;
};
double stu2[10] = {80,65,90,81,87,98,98,618,94,78};
if (student_map.find("stu2") == student_map.end()) {
std::vector<double > *vec = new std::vector<double>();
for (int i = 0; i < sizeof(stu2)/ sizeof(stu2[0]); i++) {
vec->push_back(stu2[i]);
}
student_map["stu2"] = *vec;
};
double stu3[10] = {810,165,190,811,817,981,981,618,914,718};
if (student_map.find("stu3") == student_map.end()) {
std::vector<double > *vec = new std::vector<double>();
for (int i = 0; i < sizeof(stu3)/ sizeof(stu3[0]); i++) {
vec->push_back(stu3[i]);
}
student_map["stu3"] = *vec;
};
int32_t student_number = student_map.size(); //学生个数
printf("student number, before process %d \n", (int32_t) student_map.size());
int num = 2;
//如果总个数不超过2人,则无需挑选
if (student_number > num) {
std::vector<std::pair<std::string, std::vector<double>>> tmp_student_vec; // 临时的vector
for (const auto& i : student_map) {
tmp_student_vec.push_back(i);
printf("%s \n", i.first.c_str() );
}
std::sort(tmp_student_vec.begin(), tmp_student_vec.end(),CompareWithScoreDesc2()); // 完成排序
tmp_student_vec.erase(tmp_student_vec.begin() + num, tmp_student_vec.end()); //只保留前2个
student_map.clear();
for (std::vector<std::pair<std::string, std::vector<double>>>::iterator vec_iter = tmp_student_vec.begin(); vec_iter != tmp_student_vec.end(); ++vec_iter) {
student_map.insert(std::make_pair(vec_iter->first, vec_iter->second));
printf("%s \n", vec_iter->first.c_str());
}
}
printf("student number, after process %d \n", (int32_t) student_map.size());
return 0;
}