C++自定义排序函数
每次做题都要找一遍怎么写,索性总结一下,以后方便查阅。以leetcode第一题为例,https://leetcode-cn.com/problems/two-sum/submissions/
1、写lambda函数
class Solution { public: struct NUM { NUM(int idx, int val){ this->idx = idx; this->val = val; } int idx; int val; }; vector<int> twoSum(vector<int>& nums, int target) { int n = nums.size(); vector<NUM> twoNUM; for (int i = 0; i < n; ++i) { twoNUM.emplace_back(NUM(i, nums[i])); } sort(twoNUM.begin(), twoNUM.end(), [&](NUM n1, NUM n2) { return n1.val < n2.val; }); int l = 0, r = nums.size() - 1; while (twoNUM[l].val + twoNUM[r].val != target) { if (twoNUM[l].val + twoNUM[r].val > target) { --r; } else { ++l; } } return {twoNUM[l].idx, twoNUM[r].idx}; } };
C++的struct相当于public的class。lambda函数的[&]好像是捕获参数什么的,不是很懂,但是都这么写。
2、自定义比较函数
class Solution { public: struct NUM { NUM(int idx, int val){ this->idx = idx; this->val = val; } int idx; int val; }; static bool cmp(NUM n1, NUM n2) { return n1.val < n2.val; } vector<int> twoSum(vector<int>& nums, int target) { int n = nums.size(); vector<NUM> twoNUM; for (int i = 0; i < n; ++i) { twoNUM.emplace_back(NUM(i, nums[i])); } sort(twoNUM.begin(), twoNUM.end(), cmp); int l = 0, r = nums.size() - 1; while (twoNUM[l].val + twoNUM[r].val != target) { if (twoNUM[l].val + twoNUM[r].val > target) { --r; } else { ++l; } } return {twoNUM[l].idx, twoNUM[r].idx}; } };
因为比较函数cmp放在class内所以需要加static,在class外则不需要。
3、重载比较运算符 <
class Solution { public: struct NUM { NUM(int idx, int val){ this->idx = idx; this->val = val; } int idx; int val; bool operator<(const NUM& n) const { return this->val < n.val; } }; vector<int> twoSum(vector<int>& nums, int target) { int n = nums.size(); vector<NUM> twoNUM; for (int i = 0; i < n; ++i) { twoNUM.emplace_back(NUM(i, nums[i])); } sort(twoNUM.begin(), twoNUM.end()); int l = 0, r = nums.size() - 1; while (twoNUM[l].val + twoNUM[r].val != target) { if (twoNUM[l].val + twoNUM[r].val > target) { --r; } else { ++l; } } return {twoNUM[l].idx, twoNUM[r].idx}; } };
类内重载只需要一个参数(实例)和类自己的参数比较。
4、声明比较类
class Solution { public: struct NUM { NUM(int idx, int val){ this->idx = idx; this->val = val; } int idx; int val; }; struct cmp{ bool operator() (const NUM& n1, const NUM& n2) { return n1.val < n2.val; } }; vector<int> twoSum(vector<int>& nums, int target) { int n = nums.size(); vector<NUM> twoNUM; for (int i = 0; i < n; ++i) { twoNUM.emplace_back(NUM(i, nums[i])); } sort(twoNUM.begin(), twoNUM.end(), cmp()); int l = 0, r = nums.size() - 1; while (twoNUM[l].val + twoNUM[r].val != target) { if (twoNUM[l].val + twoNUM[r].val > target) { --r; } else { ++l; } } return {twoNUM[l].idx, twoNUM[r].idx}; } };
注意这里的cmp调用时要加小括号。是因为sort要填的是实例,或者说函数(比如lambda函数)。
如果是priority_queue,则需要填写class,也就是类名,不要带括号。priority_queue<>里填三个参数,分别是元素的类型,容器(一般是vector)和比较类(不带括号)。
这里的cmp是一个类,这个类重载了()运算符。
5、基于模版的函数比较对象
升序:sort(begin,end,less<data-type>());
降序:sort(begin,end,greater<data-type>());
可用于想要降序排列时。