Reputation: 11
I have vector V = {1,2,3,4,5,6,7,8,9,10,11}
and suppose I want to create N
new vectors from this large vector.
Example : N = 3
means it will split the vector by the largest available size i.e. 4-4-3
v1 = {1,2,3,4}
v2 = {5,6,7,8}
v3 = {9,10,11}
std::vector<int> v;
for (int i = 1; i < 12; i++) v.push_back(i);
// Function here to set boundaries ???
N = 3;
v.size()/N % N
//
std::vector<int> v1(v.begin(), v.begin()+3);
std::vector<int> v2(v.begin()+4, v.begin()+7);
std::vector<int> v3(v.begin()+8, v.begin()+11);
v1,v2,v3
if it is possible.Upvotes: 0
Views: 2664
Reputation: 3460
You get get the i-th chunk of vec
if you divide into n
chunks like this:
template <typename T>
std::span<T> get_chunk(std::vector<T> const & vec, std::size_t n, std::size_t i)
{
assert(i < n);
std::size_t const q = vec.size() / n;
std::size_t const r = vec.size() % n;
auto begin = vec.begin() + i * q + std::min(i, r);
auto end = vec.begin() + (i + 1) * q + std::min(i + 1, r);
return std::span<T>(begin, end);
}
If you don't / can't use std::span
, just replace it with std::vector
or use begin
and end
-iterators directly.
Upvotes: 1
Reputation: 4864
A simple way is to build a vector
of vector
to collect the different arrays.
To control the boundaries, one possibility is first to calculate the maximum size of these arrays,
and then to manage two indices, one ibegin
corresponding to the beginning of a subarray, and one iend
corresponding to the end of the same subarray.
Output:
1 2 3 4
5 6 7 8
9 10 11
Code:
#include <iostream>
#include <vector>
std::vector<std::vector<int>> split (const std::vector<int>& v, int Nsplit) {
int n = v.size();
int size_max = n / Nsplit + (n % Nsplit != 0);
std::vector<std::vector<int>> split;
for (int ibegin = 0; ibegin < n; ibegin += size_max) {
int iend = ibegin + size_max;
if (iend > n) iend = n;
split.emplace_back (std::vector<int>(v.begin() + ibegin, v.begin() + iend));
}
return split;
}
int main() {
std::vector<int>Arr = {1,2,3,4,5,6,7,8,9,10,11};
int Nsplit = 3;
auto ans = split (Arr, Nsplit);
for (auto &v: ans) {
for (auto& i: v) {
std::cout << i << " ";
}
std::cout << std::endl;
}
return 0;
}
Upvotes: 0
Reputation: 238351
Function that does automatic creation of the vectors by itself so I don't want to manually create v1,v2,v3 if it is possible.
What could be a data structure than can hold N number of objects? How about an array? But you might want the size to be determined at runtime. How could you create an array with runtime size? Use a vector! In conclusion, write a function that creates a vector of vectors.
Note that instead of having separate vectors, it might be more efficient to keep the original vector intact, and use a vector of std::span
(prior to C++20 you can use a non-standard implementation of the same concept) pointing to the subranges.
Upvotes: 0