Получить максимальный элемент std :: vector с шагами

у меня есть std::vector<float> со следующим расположением данных

x1 | y1 | z1 | x2 | y2 | z2 | .... | xn | yn | zn

Я пытаюсь выяснить STL-иш способ получить максимум x элемент, а также y или же z

Очевидное

double xyzmax = *std::max_element(myvector.begin(),myvector.end() );

выбирает абсолютный максимум и не позволяет мне указать шаг.
Есть ли какая-то хитрость без циклов for?

2

Решение

Вот эталонная реализация std::max_element,

template<class ForwardIt>
ForwardIt max_element(ForwardIt first, ForwardIt last)
{
if (first == last) {
return last;
}
ForwardIt largest = first;
++first;
for (; first != last; ++first) {
if (*largest < *first) {
largest = first;
}
}
return largest;
}

Вы можете создать свой собственный алгоритм, изменив его следующим образом:

template<class ForwardIt>
ForwardIt max_element_nth(ForwardIt first, ForwardIt last, int n)
{
if (first == last) {
return last;
}
ForwardIt largest = first;
first += n;
for (; first < last; first += n) {
if (*largest < *first) {
largest = first;
}
}
return largest;
}

Конечно, у него есть ограничение работы только с итераторами произвольного доступа, но он, безусловно, работает для vector,

double xmax = *max_element_nth(myvector.begin(),myvector.end(), 3);
double ymax = *max_element_nth(myvector.begin()+1,myvector.end(), 3);
double zmax = *max_element_nth(myvector.begin()+2,myvector.end(), 3);

Но я бы предпочел сделать это путем сохранения значений (x, y, z) в структуре и взять вектор этого. Затем вы можете использовать стандарт max_element с пользовательским компаратором.

1

Другие решения

Вы могли бы использовать Boost.Iterator библиотека и повышение :: iterator_facade создать быстрый итератор которые могут быть начаты с std::vector<float>::iterator и для чего ++it делает it += 3; на основной итератор.

Учитывая такой итератор типа StrideItВы могли бы написать

maxX = *std::max_element(StrideIt(v.begin() + 0), StrideIt(v.end() - 2));
maxY = *std::max_element(StrideIt(v.begin() + 1), StrideIt(v.end() - 1));
maxZ = *std::max_element(StrideIt(v.begin() + 2), StrideIt(v.end() - 0));

Это предпочтительно для переопределения алгоритмов, потому что алгоритмов гораздо больше, чем типов итераторов.

Если вы хотите максимальной гибкости, вы можете сделать StrideIt шаблон класса, принимающий тип (float в вашем случае) и аргумент construtor времени выполнения, определяющий шаг (3 в вашем случае).

2

По вопросам рекламы [email protected]