使用 STL 算法在表(向量的向量、二维数组)中查找最小值/最大值的优雅方法

Posted

技术标签:

【中文标题】使用 STL 算法在表(向量的向量、二维数组)中查找最小值/最大值的优雅方法【英文标题】:Elegant way to find min/max in a table (vector of vectors, 2D array) using STL algorithm(s) 【发布时间】:2018-12-12 11:21:33 【问题描述】:

假设我们有一个向量向量并希望找到一个最小值(或最大值)(无需知道它们在表中的位置)。什么是完成此任务的优雅方式?

下面包含的显而易见的解决方案是在循环中对每一行运行 std::min_element。但是是否有可能用一个没有循环的语句来做到这一点?可能是 lambda 函数?

注意,关于 SO 已经有一个类似的问题,但实际上并不是我在这里问的问题。

更新:理想的解决方案是仅使用 STL,但如果做不到这一点,看看其他选项会很有趣。

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

int main()

    std::vector<std::vector<double> > test_array=
         
          1., 2., 3., 4.,
          7., 4., 6., 8.,
          5., -1., 3., 1
         ;
    double min_val(test_array[0][0]);
    double max_val(test_array[0][0]);
    for(auto& row : test_array)
    
        min_val = std::min(min_val, *std::min_element(row.begin(), row.end()));
        max_val = std::max(max_val, *std::max_element(row.begin(), row.end()));
    

    cout << "Minimum = " << min_val << std::endl;
    cout << "Maximum = " << max_val << std::endl;
    return 0;

【问题讨论】:

问题是算法返回一个迭代器,所以你不能做std::max_element(begin(array), end(array), 0, []()),因为你需要在一个向量上返回一个迭代器,而不是在一个元素上:/ 使用range-v3,有ranges::view::join 可以将范围范围视为展平范围,那么简单的std::minmax_element 就足够了。 @Jarod42 有机会根据它得到答案吗? @MatthieuBrucher:不确定 OP 是否可以使用外部库。 我会投票给@Jarod42。找到一种通过一个迭代器查看向量向量的方法。这可以通过一些知道所有向量的迭代器来完成。或者你将向量的向量删除为一个简单的向量。 【参考方案1】:

使用range-v3,您可能会使用ranges::view::join 获得平面视图:

std::vector<std::vector<double> > test_array =

    1., 2., 3., 4.,
    7., 4., 6., 8.,
    5., -1., 3., 1
;
auto flatten_view = test_array | ranges::view::join;
const auto p = std::minmax_element(begin(flatten_view), end(flatten_view));
std::cout << "Minimum = " << *p.first << std::endl;
std::cout << "Maximum = " << *p.second << std::endl;

Demo

【讨论】:

谢谢。我赞成您的解决方案,因为它绝对优雅且易于理解,尽管它目前不在 STL 范围内。好吧,我想一个人不能两者兼得。【参考方案2】:

有多个选项,例如,以下使用 std::accumulate 分别返回包含最小和最大元素的一对数字:

auto res = std::accumulate(a.begin(), a.end(), std::make_pair(a[0][0], a[0][0]),
    [](const auto& current, const auto& v) 
        auto minmax = std::minmax_element(v.begin(), v.end());
        return std::make_pair(std::min(current.first, *minmax.first),
                              std::max(current.second, *minmax.second));
    );

现场演示:https://wandbox.org/permlink/IwMWioewJBg7C67l

【讨论】:

有趣的解决方案。我接受它作为答案,因为它在形式上是正确的。基本上它回答了我的问题——这是可能的,但结果既不优雅也不易于理解。谢谢。 @one_two_three 同意,我们不能两者兼得。希望范围能进入 C++20。

以上是关于使用 STL 算法在表(向量的向量、二维数组)中查找最小值/最大值的优雅方法的主要内容,如果未能解决你的问题,请参考以下文章

如何从传递给某些 STL 算法的谓词中获取元素的索引?

动态数组与 STL 向量的确切区别?

将二维向量转换为二维数组

6.5-数据结构&算法-标准模板STL/STL容器/向量

将函数应用于数组向量的元素

数据结构与算法分析 - 3 - 向量