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>());

可用于想要降序排列时。

posted @ 2022-04-13 10:56  roadwide  阅读(254)  评论(0编辑  收藏  举报