Как найти максимальное значение группы массивов - PullRequest
0 голосов
/ 25 августа 2011

У меня есть шесть массивов типа float.Любой конкретный индекс во всех этих массивах представляет для меня множество значений.Например, если index 0, то все шесть массивов 0 th index представляют собой набор значений, из которых мне нужно найти максимальное значение.Точно так же и для всех других индексов.

array1  array2  array3  array4  array5  array6    
0       0       0       0       0       0 
1       1       1       1       1       1

И т. Д.

Мне нужно выяснить, какое максимальное значение определенного индекса среди всех этих массивов, и следует хранить его вдругой массив или список.

1 Ответ

2 голосов
/ 13 сентября 2011

Принимая вызов сделать это в стандартном C ++, здесь ничего не идет.

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

Я предоставляю несколько версий, начиная со стандартного кода C ++ 98 (который имеет несколько ключей, в основном для инициализации данных в контейнерах STL).

Простой стандарт C ++ 98

Смотрите вживую: http://ideone.com/2BlsK

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

template <typename Containers>
    std::vector<typename Containers::value_type::value_type> 
        reduce_minelement(const Containers& containers)
{
    typedef typename Containers::value_type slice_t;
    typedef typename Containers::const_iterator slice_ci;
    typedef typename slice_t::value_type element_t;
    std::vector<element_t> result;
    result.reserve(containers.size()); // pre-allocated

    for (slice_ci it=containers.begin(); it!=containers.end(); ++it)
    {
        result.push_back(*std::max_element(it->begin(), it->end()));
    }

    return result;
}

typedef int ints_t[6];
static const ints_t s_data[] = { 
    { 19152,     1, 21193, 17574,  8484, 30333 },
    { 20189, 18837, 30734,     2, 22440,  3534 },
        { 3, 26118, 19367, 17877, 24605,  7838 },
    { 30885, 20135,    -4, 31316, 11838,  8926 },
    { 26830, 20209, 27286, 16105, 16601, 28304 },
    { 10208, 28062, 15612, 26270, 19234, 21326 },
     { 5208, 17473,  3383, 15659, 32494, 24231 },
    { 31685, 22500, 18860, 21318, 18893, 21385 },
    { 14295, 17163,  8920, 15986, 13448, 21143 },
    { 20199,  8954,   599, 17459,  3884,  8634 },
    { 16768, 20563,  6727, 26305, 11053,  6418 },
     { 7446,  6853,  5283,  6193, 28291,  4205 },
    { 27056, 17514,  5359, 29656, 10910,  6034 },
    { 21984,  1261,  2404, 17644, 25969,  1735 },
      { 797,  8457, 23584, 29363, 26362, 17383 },
      { 768, 11018, 14991,     0, 28720,  6159 },
};

int main()
{
    std::vector<std::vector<int> > data;

    for (const ints_t *it=s_data; it!=s_data+(sizeof(s_data)/sizeof(*s_data)); ++it)
        data.push_back(std::vector<int>(*it+0, *it+sizeof(*it)/sizeof(**it)));

    std::vector<int> reduced = reduce_minelement(data);

    std::copy(reduced.begin(), reduced.end(), std::ostream_iterator<int>(std::cout, ", "));

    return 0;
}

Простой стандартный C ++ 11

Компилировать с поддержкой c ++ 0x.Преимущества:

  • значительно улучшенная инициализация
  • большая гибкость (теперь это может быть зубчатый массив, см. Демонстрационные данные)
  • разборчивость (вместо этого на основе диапазона for)циклов итераторов), auto вычитание типа
  • меньше typedef для связывания вещей

Примечание К сожалению, потому что codepad.org/ideone.com используеткомпилятор gcc 4.5.1, основанный на диапазоне for пока не поддерживается;См. Немного измененную версию в реальном времени: http://ideone.com/xevL0

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

template <typename Containers>
    std::vector<typename Containers::value_type::value_type>
         reduce_minelement(const Containers& containers)
{
    std::vector<typename Containers::value_type::value_type> result;
    result.reserve(containers.size()); // pre-allocate

    for (auto& slice: containers)
        result.push_back(*std::max_element(slice.begin(), slice.end()));

    return result;
}

static const std::vector<std::vector<int> > data = { 
       { 52,    1, 93, 74 },
        { 2,   18, 67, 77 },
       { 85,   35, -4     },
       { 48 },
       { 68,   18, 91,  0 },
};

int main()
{
    auto reduced = reduce_minelement(data);
    std::copy(reduced.begin(), reduced.end(), std::ostream_iterator<int>(std::cout, ", "));

    return 0;
}

C ++ 0x с диапазоном повышения

  • Более лаконичный код
  • позволяет работать на не-STLконтейнеры (например, массивы в стиле C) напрямую. Это приводит к несколько более сложным выводам типа в reduce_minelement.Абстракция имеет свою цену;)

Примечание данные (s_data) опущены, поскольку они идентичны приведенным выше;вы можете добавить одно из s_data определений из других примеров, и оно скомпилируется и запустится.

Примечание Никакая онлайн-служба компилятора не поддерживает заголовки библиотеки Boost, так что вы можете увидеть это live только дома.

#include <vector>
#include <boost/range.hpp>
#include <boost/range/algorithm.hpp>
#include <iterator>

using boost::range_value;
using boost::range_iterator;

template <typename Containers>
    std::vector<typename range_value<typename range_value<Containers>::type>::type> 
         reduce_minelement(const Containers& containers)
{
    std::vector<typename range_value<typename range_value<Containers>::type>::type> result;
    result.reserve(boost::size(containers)); // pre-allocate

    for (auto& slice: containers)
        result.push_back(*boost::max_element(slice));

    return result;
}

typedef int ints_t[6];
static const ints_t s_data[] = { 
    { 19152,     1, 21193, 17574,  8484, 30333 },
    { 20189, 18837, 30734,     2, 22440,  3534 },
        { 3, 26118, 19367, 17877, 24605,  7838 },
    { 30885, 20135,    -4, 31316, 11838,  8926 },
    { 26830, 20209, 27286, 16105, 16601, 28304 },
    { 10208, 28062, 15612, 26270, 19234, 21326 },
     { 5208, 17473,  3383, 15659, 32494, 24231 },
    { 31685, 22500, 18860, 21318, 18893, 21385 },
    { 14295, 17163,  8920, 15986, 13448, 21143 },
    { 20199,  8954,   599, 17459,  3884,  8634 },
    { 16768, 20563,  6727, 26305, 11053,  6418 },
     { 7446,  6853,  5283,  6193, 28291,  4205 },
    { 27056, 17514,  5359, 29656, 10910,  6034 },
    { 21984,  1261,  2404, 17644, 25969,  1735 },
      { 797,  8457, 23584, 29363, 26362, 17383 },
      { 768, 11018, 14991,     0, 28720,  6159 },
};

int main()
{
    boost::copy(reduce_minelement(s_data), std::ostream_iterator<int>(std::cout, ", "));

    return 0;
}

Универсальность: как насчет строк?

Все три версии являются полностью общими для типа элемента.В некоторых других местах может потребоваться корректировка (например, тип ostream_iterator), но фактическая реализация не имеет значения, добавляете ли вы float s, std::string s, integers или, действительно, любой сопоставимый тип.

Демоверсия, основанная на последней версии:

typedef std::string elements_t[3];
static const elements_t s_data[] = { 
    { "the", "quick", "fox" },
    { "jumped", "over", "the" },
    { "lazy", "blue", "moon" },
};

int main()
{
    boost::copy(reduce_minelement(s_data), 
       std::ostream_iterator<std::string>(std::cout, ", "));

    return 0;
}

Выход:

, луна,

QED

Надеюсь, это было интересно для вас.Это было для меня.

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