Добавление диапазонов в цикле

Я хотел бы объединить диапазоны, возвращаемые функцией, в один большой диапазон. Рассмотрим следующий код:

some_type_i_cant_figure_out bar() {
typedef std::vector<int>::const_iterator iter;
std::vector<int> aaa;
/* fill some data into aaa*/
some_type_i_cant_figure_out cc;
for (int i = 0; i < aaa.size(); ++i) {
std::pair<iter, iter> bbb = foo(aaa, i);
ccc = boost::join(ccc, bbb);
}
return ccc;
}

Чего я пытаюсь добиться:
Вектор aaa огромен, и foo может возвращать довольно большие диапазоны. Конечно, я могу просто создать копии всех элементов в диапазоне в новый вектор целых чисел и вернуть его. Это неэффективно, тратя впустую память и время. Поэтому я хотел бы вернуть один boost :: join_range. В худшем случае я могу жить с вектором диапазонов, но это было бы слишком просто и не так уж и элегантно 🙂
кроме join_range не является конструируемым по умолчанию (что проблематично для реализации данного примера), что будет тип возвращаемого значения? тип временной переменной (ccc) и каков будет правильный и элегантный способ достижения вышеуказанного?

2

Решение

Во-первых, конечный результат вашего кода будет похож на просто

auto cc(aaa);
boost::stable_sort(cc);

(Исходя из вашего примера кода, что aaa содержит целые числа в диапазоне [0..size()-1))

Если вы можете позволить себе просто скопировать, просто используйте итератор backinsert:

std::vector<int> cc;
for (size_t i = 0; i < aaa.size(); ++i)
boost::copy(boost::equal_range(aaa, i), back_inserter(cc));

В противном случае вы можете скрыть накапливающиеся объединения, используя any_range:

boost::any_range<int, boost::forward_traversal_tag, int> r;
for (size_t i = 0; i < aaa.size(); ++i)
r = boost::join(r, boost::equal_range(aaa, i));

Жить на Колиру

#include <boost/range/any_range.hpp>
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
#include <iostream>

int main() {
std::vector<int> const aaa { 1,1,1,4,5,5,9,42,42,42,42,42,42 };

boost::any_range<int, boost::forward_traversal_tag, int> r;
for (size_t i = 0; i < aaa.size(); ++i)
r = boost::join(r, boost::equal_range(aaa, i));

boost::copy(r, std::ostream_iterator<int>(std::cout << "result: ", " "));
}

Печать

result: 1 1 1 4 5 5 9
1

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


По вопросам рекламы ammmcru@yandex.ru
Adblock
detector