Элегантный способ найти мин / макс в таблице (вектор векторов, двумерный массив), используя алгоритм (ы) STL - PullRequest
0 голосов
/ 12 декабря 2018

Допустим, у нас есть вектор векторов и мы хотим найти минимальные (или максимальные) значения (не нужно знать их положение в таблице).Что было бы элегантным способом сделать это?

Очевидное решение, включенное ниже, заключается в запуске std :: min_element для каждой строки в цикле.Но, может быть, это возможно сделать с помощью одного оператора без цикла, используя, может быть, лямбда-функции?

Обратите внимание, что в 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;
}

Ответы [ 2 ]

0 голосов
/ 12 декабря 2018

С 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

0 голосов
/ 12 декабря 2018

Существует несколько опций, например, следующая использует 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...