Есть ли более идиоматический способ разбить std :: vector?

Я написал функцию, которая разбивает вектор размера N на куски размером не более М.

Таким образом, с учетом вектора размера 47 и размера фрагмента 10 мы получаем 5 фрагментов размером: 10,10,10,10,7.

template<typename T> std::vector<std::vector<T>> chunkVector(typename std::vector<T> source, typename std::vector<T>::size_type chunkSize)
{
typename std::vector<std::vector<T>> returnVector;

for (typename std::vector<T>::size_type i = 0; i < source.size(); i += chunkSize) {

typename std::vector<T>::iterator start = source.begin() + i;
typename std::vector<T>::iterator end = start + chunkSize > source.end() ? source.end() : start + chunkSize;
typename std::vector<T> tempVector(start, end);

returnVector.push_back(tempVector);
}
return returnVector;
}

Есть ли более идиоматический способ сделать это? Требование итераторов random_access подсказывает мне, что может быть более удачный способ.

2

Решение

Единственное, что я бы сделал по-другому, это как итерировать и как мы добавляем в вектор результатов:

template<typename T>
std::vector<std::vector<T>> chunkVector(const std::vector<T>& source, size_t chunkSize)
{
std::vector<std::vector<T>> result;
result.reserve((source.size() + chunkSize - 1) / chunkSize);

auto start = source.begin();
auto end = source.end();

while (start != end) {
auto next = std::distance(start, end) <= chunkSize
? start + chunkSize
: end;

result.emplace_back(start, next);
start = next;
}

return result;
}
3

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


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