我必须对一个 vector 进行排序。该 vector 包含指向“student”类对象的指针。
评级指标如下所示:
- 最好的期末成绩
- 如果期末成绩相同,则尝试次数较少
- 如果相同的尝试,更少的id
- 尝试次数为 0 次的学生比尝试次数为 2 次且最终成绩为 5 的学生差,尝试次数为 0 次的学生按较少的 id 排序
学生看起来像这样:
private:
std::string name_;
int id_;
int attempts_; //max 2, if 0, exam not taken
int grade1_;
int grade2_;
int finalGrade_; // grade 5 for failed exam but still better than 0 attempts in rating
我的问题是我不知道如何处理尝试。因为最佳尝试次数是 1 次,比 2 次更好。但 2 次尝试的评分优于 0 分。
我希望你能理解我的问题并能帮助我。谢谢:)
最佳答案
STL 中有一个可用的函数,称为std::sort
它可以采用比较器函数(函数指针或函数对象)。
比较器函数必须返回一个 bool 值,表示第一个元素是否应该严格出现在第二个元素之前。
这是我为比较器想出的:
struct compare_student {
inline bool
operator() (Student *left, Student *right) const
{
if(left->attempts_ == 0 && right->attempts_ == 0)
return left->id_ < right->id_;
else if(left->attempts_ == 0)
return false;
else if(right->attempts_ == 0)
return true;
return
left->finalGrade_ < right->finalGrade_ || // Compare final grade
left->finalGrade_ == right->finalGrade_ && ( // If final grade same:
left->attempts_ < right->attempts_ || // Compare attempts
left->attempts_ == right->attempts_ && ( // If attempts same:
left->id_ < right->id_ // Compare id's
)
);
}
};
显然您的所有字段都是私有(private)的,因此您需要使用它们的访问器方法而不是直接访问它们,但这是您如何使用它:
vector<Student *> students {...};
std::sort(students.begin(), students.end(), compare_student{});
std::sort
不稳定,这意味着如果两个元素被认为是相等的,那么它们不一定会保持它们的相对顺序,这对您来说可能很重要。如果是,那么还有一个名为 std::stable_sort
的函数确实有这样的保证,并且以完全相同的方式使用:
std::stable_sort(students.begin(), students.end(), compare_students{});
编辑 实现说明
compare_students
是一个只有一个公共(public)成员的类,所以不要这样做:class compare_student { public: ... };
我把它缩短为:
struct compare_student { ... };
(两者在 C++ 中是等价的,struct 只是一个具有默认公共(public)访问权限的类。)
然后至于
inline bool operator()
是什么意思。inline
是给编译器的提示,这个函数可以被内联,也就是说,用代码本身替换调用。bool
是函数的返回类型。operator()
是函数的名称,它是一个特殊情况的函数,当您将对象视为函数时,它会被调用:Student *a, *b; compare_student comparator {}; comparator(a, b); // calls comparator::operator()(a, b)
关于c++ - 按多个值对 vector 进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21224655/