c++ - 试图用 lambda 找到二维 vector 的最小元素

标签 c++ c++11 lambda std

我目前正在尝试找到二维 vector 的最小元素。我正在尝试使用 C++11 lambda 函数进行练习,并认为这可能是一种很好的做法,但似乎无法对其进行编译。
我知道我可以执行以下操作:

vector<vector<int>> matrix = {
                                {1, 2, 3, 4, 5 },
                                {6, 7, 8, 9, 10 },
                                {5, 6, 8, 1, 12 },
                                {1, 7, 2, 4, 18 },
};

int result = std::numeric_limits<int>::max();
for(const auto& row : matrix)
{
  int minElemInRow = *std::min_element(row.begin(), row.end());
  result = std::min(result , minElemInRow);
}
return result;

但想知道是否可以使用 lambda 函数完成同样的操作。目前,这是我最好的尝试:
vector<vector<int>> matrix = {
                                {1, 2, 3, 4, 5 },
                                {6, 7, 8, 9, 10 },
                                {5, 6, 8, 1, 12 },
                                {1, 7, 2, 4, 18 },
};

return *std::min_element(matrix.begin(), matrix.end(), 
  [](const auto& row)
  {
    return *std::min_element(row.begin(), row.end());
  });

我收到错误:错误 C2672 : 'operator __surrogate_func': 找不到匹配的重载函数
我觉得它应该如何工作是外部 min_element 将一次传入一行(这只是对 vector 的引用),从中我可以返回最小的,然后将其与其他行进行比较。
我认为问题可能在于 lambda 会接收到 int vector 的迭代器,而不是对 int vector 的引用,但取消引用似乎没有帮助。
有没有更好的方法来做我想做的事情?
@assembly_wizard 指出 min_element 需要一个谓词,它可以比较传递给它的两个项目。那是两排。这导致以下代码:
vector<vector<int>> matrix = {
                                {1, 2, 3, 4, 5 },
                                {6, 7, 8, 9, 10 },
                                {5, 6, 8, 1, 12 },
                                {1, 7, 2, 4, 18 },
};

auto i = std::min_element(matrix.begin(), matrix.end(),
        [](const auto& lhs, const auto& rhs)
{
        return *std::min_element(lhs.begin(), lhs.end()) <
            *std::min_element(rhs.begin(), rhs.end());
});
这将找到具有最小元素的行。虽然我可以通过将它包装在另一个 std::min_element 中来完成这项工作,但这比远程帮助要复杂得多。如果有人有更好的建议,我很想听听!

最佳答案

我已经编译了一个工作版本,它执行我在评论中提到的内容:

#include <vector>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<std::vector<int>> matrix = {
        {1, 2, 3, 4, 5 },
        {6, 7, 8, 9, 10 },
        {5, 6, 8, 1, 12 },
        {1, 7, 2, 4, 18 },
    };

    std::vector<int> row_minimums(matrix.size());
    std::transform(matrix.begin(), matrix.end(), row_minimums.begin(), [](const auto& row) {
        return *std::min_element(row.begin(), row.end());
    });
    auto i = *std::min_element(row_minimums.begin(), row_minimums.end());

    std::cout << "Minimum element is: " << i << std::endl;
}
See it in action on godbolt
这将分别取每行的最小值,所以我们得到 row_minimums这是一个整数 vector ,然后取其中的最小值来获得所有行之间的最终结果。
唯一使这段代码比 for 更糟糕的事情循环版本,是它保留了所有 row_minimums在运行之前立即在内存中 min_element在他们。不幸的是,我不知道有什么办法可以同时做到这一点,但我不是 STL 最期待的人,所以也许有办法。
您可能会考虑的其他选项是首先将二维矩阵连接成一维 vector ,然后使用 min_element在它上面,或者你在编辑中包含的选项,你调用 min_element 3次。
另外,this SO answer似乎有关于使用 boost 的解决方案的有趣信息图书馆可能会更好,但我不确定它们到底是什么。

关于c++ - 试图用 lambda 找到二维 vector 的最小元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65227007/

相关文章:

c++ - 为类 move 构造函数和 move 赋值运算符

c++ - decltype 的模板参数数量不正确。

c++ - 等效于使用 lambda 的 python 映射函数

c++ - 传递给 lambda 函数的空指针不再为空

Java 8 Streams.reduce() 与组合器

c++ - OpenCV如何在二进制图像中找到连接组件的列表

c++ - C++ 中的运算符 |= 及其用法

c++ - std::string 到 std::chrono time_point

c++ - 如何解决地址问题

c++ - 无法取消引用超出范围的 vector 迭代器 - 有什么问题?