按多个值排序矢量

d0z*_*zer 3 c++ sorting vector

我必须对矢量进行排序.该向量包含指向"student"类对象的指针.

评级指标如下所示:

  1. 最佳的最终评级
  2. 如果相同的最终级别,更少尝试
  3. 如果相同的尝试,更少的身份
  4. 0次尝试的学生比2次尝试和最终级别5的学生更差,按0次尝试将0次尝试排序

学生看起来像这样:

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
Run Code Online (Sandbox Code Playgroud)

我的问题是我不知道如何处理尝试.因为最佳尝试次数为1次,优于2次尝试次数.但是2次尝试在评级中优于0.

我希望你能理解我的问题,并能帮助我.谢谢 :)

amn*_*mnn 8

STL中有一个函数,称为std::sort可以采用比较器函数(函数指针或函数对象).

比较器函数必须返回一个布尔值,该布尔值表示第一个元素是否应该严格出现在第二个元素之前.

以下是我为比较器提出的建议:

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
                )
            );
    }
};
Run Code Online (Sandbox Code Playgroud)

显然你的所有字段都是私有的,所以你需要使用它们的访问器方法,而不是直接访问它们,但这里是你如何使用它:

vector<Student *> students {...};
std::sort(students.begin(), students.end(), compare_student{});
Run Code Online (Sandbox Code Playgroud)

std::sort不稳定,这意味着如果两个元素被认为是相等的,那么它们不一定会保持它们的相对顺序,这对你来说可能很重要.如果是,那么就调用的函数std::stable_sort,其确实有这样的保证,以完全相同的方式使用:

std::stable_sort(students.begin(), students.end(), compare_students{});
Run Code Online (Sandbox Code Playgroud)

编辑 关于实施的说明

  • compare_students 是一个只有一个公共成员的类,所以不要这样做:

    class compare_student {
    public:
        ...
    };
    
    Run Code Online (Sandbox Code Playgroud)

    我把它简化为:

    struct compare_student {
        ...
    };
    
    Run Code Online (Sandbox Code Playgroud)

    (这两个在C++中是等价的,struct只是一个具有默认公共访问权的类.)

  • 那是什么inline bool operator()意思.

    • inline 是一个提示编译器可以内联此函数,也就是说,用代码本身替换调用.
    • bool 是函数的返回类型.
    • operator() 是函数的名称,它是一个特殊情况函数,当你像对待函数一样处理对象时会调用它:

      Student *a, *b;
      compare_student comparator {};
      
      comparator(a, b); // calls comparator::operator()(a, b)
      
      Run Code Online (Sandbox Code Playgroud)