试图用 lambda 找到 2D 向量的最小元素
Trying to find the minimum element of 2D vector with lambda
我目前正在尝试查找二维向量的最小元素。我正在尝试练习使用 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());
});
我收到错误:error C2672:'operator __surrogate_func':找不到匹配的重载函数
我觉得它应该起作用的是外部 min_element 将一次连续传递(这只是对向量的引用),从中我可以 return最小的,然后将与其他行进行比较。
我认为问题可能是 lambda 将接收一个指向整数向量的迭代器而不是对整数向量的引用,但取消引用似乎没有帮助。
有没有更好的方法来做我想做的事情?
@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;
}
这将分别取每一行的最小值,所以我们得到 row_minimums
这是一个整数向量,然后取这些中的最小值得到所有行之间的最终结果。
唯一使此代码比 for
循环版本更糟糕的是,它在 运行 min_element
之前立即将所有 row_minimums
保存在内存中在他们。不幸的是,我不知道有什么方法可以同时做到这一点,但我不是最棒的 STL 期望,所以也许有办法。
您可能考虑的其他选项是首先将 2D 矩阵连接成 1D 向量,然后在其上使用 min_element
,或者您在编辑中包含的选项,您调用 min_element
3次。
此外,this SO answer 似乎有关于使用 boost
库的解决方案的有趣信息,这可能更好,但我不确定它们到底是什么。
简单一点:
使用 std::for_each 遍历矩阵中的每个向量,并获得它们的最小元素。由于 min
是通过引用捕获的,因此您会得到所有这些的最小值。
#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 },
};
int min = std::numeric_limits<int>::max();
std::for_each(matrix.begin(), matrix.end(),
[&min](const auto& v)
{
min = std::min(*min_element(v.begin(), v.end()), min);
}
);
std::cout << "Minimum element is: " << min << std::endl;
}
我目前正在尝试查找二维向量的最小元素。我正在尝试练习使用 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());
});
我收到错误:error C2672:'operator __surrogate_func':找不到匹配的重载函数
我觉得它应该起作用的是外部 min_element 将一次连续传递(这只是对向量的引用),从中我可以 return最小的,然后将与其他行进行比较。
我认为问题可能是 lambda 将接收一个指向整数向量的迭代器而不是对整数向量的引用,但取消引用似乎没有帮助。
有没有更好的方法来做我想做的事情?
@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;
}
这将分别取每一行的最小值,所以我们得到 row_minimums
这是一个整数向量,然后取这些中的最小值得到所有行之间的最终结果。
唯一使此代码比 for
循环版本更糟糕的是,它在 运行 min_element
之前立即将所有 row_minimums
保存在内存中在他们。不幸的是,我不知道有什么方法可以同时做到这一点,但我不是最棒的 STL 期望,所以也许有办法。
您可能考虑的其他选项是首先将 2D 矩阵连接成 1D 向量,然后在其上使用 min_element
,或者您在编辑中包含的选项,您调用 min_element
3次。
此外,this SO answer 似乎有关于使用 boost
库的解决方案的有趣信息,这可能更好,但我不确定它们到底是什么。
简单一点:
使用 std::for_each 遍历矩阵中的每个向量,并获得它们的最小元素。由于 min
是通过引用捕获的,因此您会得到所有这些的最小值。
#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 },
};
int min = std::numeric_limits<int>::max();
std::for_each(matrix.begin(), matrix.end(),
[&min](const auto& v)
{
min = std::min(*min_element(v.begin(), v.end()), min);
}
);
std::cout << "Minimum element is: " << min << std::endl;
}