c++ - 按多个值对 vector 进行排序

标签 c++ sorting vector

我必须对一个 vector 进行排序。该 vector 包含指向“student”类对象的指针。

评级指标如下所示:

  1. 最好的期末成绩
  2. 如果期末成绩相同,则尝试次数较少
  3. 如果相同的尝试,更少的id
  4. 尝试次数为 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/

相关文章:

c++ - 如何从用户那里获取输入并将其推送到列表

javascript - 对 jQuery 数据表中的数字进行排序

c++ - 为什么当 cout 显示正确大小时 printf 显示 vector 大小为 0?

c++ - 将派生类指针的 vector 传递给线程

将 std::string 作为函数参数传递时的 C++ 类型转换

c++ - 在 C++ 中如何在 arm 架构中检测 EOF

python - 根据分数重新排列列表项以适应函数曲线

c++ - Gtkmm:将 RefPtr 与保存在 std::vector 中的小部件一起使用

C++ : What is happening when a non-overridden calls a overridden method?

java - 按字母顺序对对象进行排序