在CSP - J备考的冲刺阶段,STL(标准模板库)的高级技巧是非常重要的内容,其中自定义仿函数更是需要重点掌握的部分。
一、自定义仿函数的概念及意义
自定义仿函数简单来说就是一种可以像函数一样被调用的对象。在STL中,像sort(排序算法)和priority_queue(优先队列)等组件,它们默认有一些比较规则,但很多时候我们需要根据自己的需求来定制排序或者比较逻辑。这时候自定义仿函数就派上用场了。
二、为sort编写自定义比较函数(结构体重载()运算符)
- 知识点内容
- 当我们要对一个数组或者容器中的元素按照特定规则排序时,比如对一个结构体类型的数组进行排序。假设我们有一个结构体表示学生的信息,包含姓名、年龄和成绩三个字段。
- 如果我们想按照成绩降序排序,对于结构体类型,可以通过重载()运算符来实现自定义比较函数。
- 例如:
struct Student {
string name;
int age;
double score;
bool operator()(const Student& s1, const Student& s2) const {
return s1.score > s2.score;
}
};
- 这里的重载()运算符定义了一个比较规则,即比较两个学生的成绩,如果第一个学生的成绩大于第二个学生的成绩,就返回true。
- 学习方法
- 理解结构体的成员变量与比较逻辑的关系。首先要明确我们想要根据哪个成员变量或者哪些成员变量的组合来进行比较。
- 多做一些简单的练习题,例如对不同结构体类型按照单一字段或者多字段进行排序的题目。可以从简单的按照一个整数字段排序开始,逐渐过渡到复杂的结构体排序。
三、为priority_queue编写自定义比较函数
- 知识点内容
- priority_queue默认是大顶堆(最大元素在队首),如果我们想要构建小顶堆或者按照其他自定义规则构建优先队列,就需要自定义仿函数。
- 例如,同样对于上述的学生结构体,如果我们想构建一个小顶堆,按照年龄排序:
struct cmp {
bool operator()(const Student& s1, const Student& s2) const {
return s1.age > s2.age;
}
};
priority_queue<Student, vector<Student>, cmp> pq;
- 这里定义了一个名为cmp的结构体作为仿函数,在创建priority_queue时将其作为第三个模板参数传入。
- 学习方法
- 区分不同容器对于比较函数的需求差异。比如priority_queue与sort在使用自定义比较函数时的语法和逻辑上的不同之处。
- 通过实际的代码调试来加深理解。可以自己编写一些包含不同类型元素的priority_queue,尝试不同的比较函数,观察队列元素的排列顺序是否符合预期。
四、结构体多字段排序的实现细节
- 知识点内容
- 当按照结构体的多个字段进行排序时,要确定每个字段的优先级。例如先按照成绩降序排序,如果成绩相同再按照年龄升序排序。
- 对应的比较函数可以这样写:
struct Student {
string name;
int age;
double score;
bool operator()(const Student& s1, const Student& s2) const {
if (s1.score!= s2.score) {
return s1.score > s2.score;
} else {
return s1.age < s2.age;
}
}
};
- 这里先比较成绩,如果不相等就按照成绩降序排列;如果成绩相等,就按照年龄升序排列。
- 学习方法
- 画图辅助理解。可以将结构体元素想象成多维空间中的点,每个字段就是一个维度,通过画图来直观地理解多字段排序的逻辑顺序。
- 分析实际问题中的排序需求。从生活中的场景出发,比如对员工按照工资、工龄等多方面因素进行排序,然后将这种需求转化为代码中的多字段排序逻辑。
总之,在CSP - J备考的冲刺阶段,要熟练掌握STL中自定义仿函数的用法,通过大量的练习和对知识点的深入理解,才能在考试中灵活运用这些技巧解决相关的问题。
喵呜刷题:让学习像火箭一样快速,快来微信扫码,体验免费刷题服务,开启你的学习加速器!