按多个值排序矢量

时间:2014-01-20 00:53:00

标签: c++ sorting vector

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

评级指标如下所示:

  1. best finalgrade
  2. 如果是相同的最终级别,则尝试次数较少
  3. 如果尝试次数相同,则为id
  4. 0次尝试的学生比2次尝试的学生更差,并且最终评分为5次,按0次尝试排序0次学生
  5. 学生看起来像这样:

    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。

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

2 个答案:

答案 0 :(得分: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
                )
            );
    }
};

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

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是一个只有一个公共成员的类,所以不要这样做:

    class compare_student {
    public:
        ...
    };
    

    我把它简化为:

    struct compare_student {
        ...
    };
    

    (两者在C ++中是等价的,结构只是一个具有默认公共访问权的类。)

  • 然后关于inline bool operator()的含义。

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

      Student *a, *b;
      compare_student comparator {};
      
      comparator(a, b); // calls comparator::operator()(a, b)
      

答案 1 :(得分:1)

听起来比较函数的第一行应该是

if (left.attempts_ == 0)

从那里,检查是否right.attempts_ == 0。如果是,请检查ID。

如果不是,那么右边有一个等级而左边没有,右边有更好。

继续执行其余规则。最终,您可以使用if (left.attempts_ < right.attempts_)之类的规则,但只有在您处理0次尝试后才能使用。