【问题标题】:How to use a functor instead of lambda function如何使用仿函数而不是 lambda 函数
【发布时间】:2019-08-11 14:30:30
【问题描述】:

我试图通过 Leetcode 解决一个问题。

问题描述:

给定一个 n x n 矩阵,其中每一行和每一列都按升序排序,找到矩阵中第 k 个最小的元素。

请注意,它是排序顺序中第 k 个最小的元素,而不是第 k 个不同的元素。

我是这样解决的:

class Solution {
public:
    int kthSmallest(std::vector<std::vector<int>>& matrix, int k) {

        auto comp_gt = [&matrix](std::pair<int ,int> a, std::pair<int ,int> b)
        {
            return matrix[a.first][a.second] > matrix[b.first][b.second];
        };

        m = matrix.size();
        if (m == 0) return 0;
        n = matrix[0].size();
        if (n == 0) return 0;        

        std::priority_queue<std::pair<int, int>, 
                            std::vector<std::pair<int, int>>, 
                            decltype(comp_gt)> min_heap(comp_gt);

        for (int j = 0; j < n; ++j)
        {
            min_heap.emplace(0, j);
        }

        for (int i = 0; i < k-1; ++i)
        {
            int r = min_heap.top().first;
            int c = min_heap.top().second;
            min_heap.pop();

            if (r != m - 1)
            {
                min_heap.emplace(r+1, c);
            }
        }

        return matrix[min_heap.top().first][min_heap.top().second];
    }

private:
    int m;
    int n;
};

此代码有效。但是,当我尝试用函子替换 lambda 函数时,我将函子写成这样:

class comp_gt
{
    bool operator () (std::pair<int, int> a, std::pair<int, int> b, std::vector<std::vector<int>>& matrix)
    {
        return matrix[a.first][a.second] > matrix[b.first][b.second];
    }
};

然后我意识到我不知道如何在 lambda 函数中将 matrix 传递给像 [&amp;matrix] 这样的函子。

谁能帮忙?

【问题讨论】:

    标签: c++ priority-queue functor


    【解决方案1】:

    您需要在仿函数的构造函数中传递引用。请注意,以下代码等效于您的 lambda,但带有 mutable 修饰符。

    class comp_gt
    {
    
        public:
            using Matrix = std::vector<std::vector<int>>;
    
            comp_gt(Matrix& matrix) : matrix{matrix}{}
            bool operator () (std::pair<int, int> a, std::pair<int, int> b, std::vector<std::vector<int>>& matrix)
            {
                 return matrix[a.first][a.second] > matrix[b.first][b.second];
            }
    
        private:
    
            Matrix& matrix;
    
    };
    

    然后将其用作:

    comp_gt comp{matrix};
    

    【讨论】:

    • 据我所知,重载运算符应该只为priority_queues 取两个参数。为什么priority_queue不会将函数对象作为自定义比较器创建编译/链接错误,该比较器具有带有第三个附加参数'matrix'的重载函数运算符?
    【解决方案2】:

    “如何使用仿函数而不是 lambda 函数” - 使用 operator() 创建一个类(可以选择捕获变量)。 lambda 只不过是语法糖(一种更简单的方法)来编写这样的(函子)类。

    【讨论】:

      【解决方案3】:

      这是通过将其传递给比较器的构造函数来完成的:

      class comp_gt
      {
        std::vector<std::vector<int>>& matrix;
      
        comp_gt(std::vector<std::vector<int>>& matrix) : matrix{matrix} {}
      

      现在,你现有的operator()可以正常使用了。

      然后,当您实际构建比较器时,您只需正常构建它并将适当的参数传递给构造函数。假设您想将比较器与std::sort 一起使用:

      comp_gt comparator{some_matrix};
      
      std::sort(something.begin(), something.end(), comparator);
      

      将此比较器与std::priority_queue 使用类似。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 1970-01-01
        • 2019-09-12
        • 2014-05-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多