如何基于最小courseId对存储GolfCourse*集合的deque排序
解决
deque<set<GolfCourse*>>按每个set最小courseId排序的问题 我完全懂你的困扰——默认的std::sort会用set的默认比较逻辑(也就是指针地址对比),这肯定不符合你按courseId排序的需求。别慌,咱们自定义一个比较规则就能搞定,而且其实很简单!
核心思路
你的set已经通过SortFunctor按courseId升序排序了,所以每个非空set的第一个元素就是courseId最小的GolfCourse对象。我们只需要给std::sort传入一个自定义的比较函数/ Lambda,让它根据这个最小courseId来排序deque的元素,同时处理空set的情况(你说空元素位置不做要求,这里我默认把空set放到排序后的末尾,你也可以调整逻辑放到前面)。
具体实现步骤
1. 确认你的SortFunctor是正确的
首先要确保你的set确实是按courseId升序排列的,比如你的仿函数应该是这样的:
struct SortFunctor { bool operator()(const GolfCourse* lhs, const GolfCourse* rhs) const { return lhs->courseId < rhs->courseId; } };
这样set的begin()迭代器指向的就是当前set中courseId最小的对象。
2. 自定义比较逻辑(两种方式)
方式一:单独写比较函数
如果你喜欢把逻辑抽出来,可以定义一个全局或者命名空间内的比较函数:
#include <deque> #include <set> #include <algorithm> // 假设你的GolfCourse结构是这样的 struct GolfCourse { int courseId; std::string courseName; int courseSlope; }; struct SortFunctor { bool operator()(const GolfCourse* lhs, const GolfCourse* rhs) const { return lhs->courseId < rhs->courseId; } }; // 自定义deque元素的比较函数 bool compareTrailElements(const std::set<GolfCourse*, SortFunctor>& trailA, const std::set<GolfCourse*, SortFunctor>& trailB) { // 处理空set的情况:两个都空,不需要交换 if (trailA.empty() && trailB.empty()) { return false; } // trailA是空的,放到后面,所以返回false(表示trailA不应该在trailB前面) if (trailA.empty()) { return false; } // trailB是空的,trailA应该在前面,返回true if (trailB.empty()) { return true; } // 非空情况:取第一个元素的courseId比较 return (*trailA.begin())->courseId < (*trailB.begin())->courseId; }
然后调用sort的时候传入这个函数:
std::deque<std::set<GolfCourse*, SortFunctor>> golfTrails; // 假设你已经给golfTrails填充了数据 std::sort(golfTrails.begin(), golfTrails.end(), compareTrailElements);
方式二:用Lambda表达式(更简洁)
如果不想单独写函数,直接用Lambda表达式传入sort会更方便:
std::sort(golfTrails.begin(), golfTrails.end(), [](const std::set<GolfCourse*, SortFunctor>& trailA, const std::set<GolfCourse*, SortFunctor>& trailB) { if (trailA.empty() && trailB.empty()) return false; if (trailA.empty()) return false; if (trailB.empty()) return true; return (*trailA.begin())->courseId < (*trailB.begin())->courseId; });
为什么之前的尝试可能失败?
你提到之前传递比较运算符或者定义deque时用仿函数没成功,大概率是这几个原因:
- 没有正确处理空
set的情况,导致访问空set的begin()出现未定义行为 - 比较函数的参数类型和
deque的元素类型不匹配(比如没加const引用,或者写错了set的模板参数) - 解引用指针时出错,比如忘了用
->courseId,直接比较了指针地址
验证示例
比如你给出的测试场景:
- 第1个set:courseId 2、4、7、10 → 最小是2
- 第2个set:3、5、6 → 最小是3
- 第3个set:空
- 第4个set:1、8、9 → 最小是1
排序后deque的顺序就会是:第4个(1)→ 第1个(2)→ 第2个(3)→ 第3个(空),完全符合你的需求。
内容的提问来源于stack exchange,提问作者Lily Bristol
相关产品推荐
相关产品推荐

