简体   繁体   中英

Elegant way to find min/max in a table (vector of vectors, 2D array) using STL algorithm(s)

Let us assume we have a vector of vectors and wish to find a minimum (or maximum) values (no need to know their position in the table). What would be an elegant way to accomplish this?

The obvious solution, included below, is to run std::min_element per each row in a loop. But may be it is possible to do it with a single statement without loop using, may be, lambda functions?

Note, there is a similar question on SO already, but it is actually not quite about what I am asking here.

Update: Ideal solution would be using STL only, but, failing that, it would be interesting to see other options.

#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;
}

With range-v3 , you might have a flatten view with 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

There are multiple options, eg, the following one uses std::accumulate that returns pair of numbers containing minimum and maximum elements, respectively:

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

Live demo: https://wandbox.org/permlink/IwMWioewJBg7C67l

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM