I want to create a second array with exactly the same dimensions as an original jagged array. I've illustrated the desired result below when using a 3D vector.
std::vector<std::vector<std::vector<int>>> old_vector;
old_vector = {
{
{1,2,3},
{1,2,3,4}
},
{
{1,2}
},
{
{1,2,3,4},
{1,2}
}
};
std::vector<std::vector<std::vector<int>>> new_vector;
// Do something to 'new_vector'...
new_vector = {
{
{},
{}
},
{
{}
},
{
{},
{}
}
};
I've come up with the following solution.
std::vector<std::vector<std::vector<int>>> new_vector;
for (int i = 0; i < old_vector.size(); i ) {
std::vector<std::vector<int>> tmp_array(old_vector[i].size());
new_vector.push_back(tmp_array);
}
This works, but it does not seem like a very efficient solution. So, I was wondering whether there might exist a better alternative that perhaps does not need to loop through every element of the original vector? Something like a copy that only copies the dimensions of the arrays, but not the actual values?
CodePudding user response:
template<class T>
using vec2d=std::vector<std::vector<T>>;
template<class T>
vec2d<T> same_jagged_size_as( vec2d<T> const& v ){
vec2d<T> retval;
revtal.reserve(v.size());
ranges::transform(
v, std::back_inserter(retval),
[](auto&v) { return std::vector<T>(v.size()); }
);
return retval;
}
CodePudding user response:
Here's how I would do it.
template<typename T>
concept is_resizeable = requires (T a)
{
a.size();
a.resize(1);
};
template <typename T>
void reshape(std::vector<T>& to, const std::vector<T>& from)
{
to.resize(from.size());
if constexpr(is_resizeable<T>)
{
for (unsigned i = 0; i < from.size(); i)
{
reshape(to[i], from[i]);
}
}
}
This will work with any nesting level of vectors.
CodePudding user response:
You can implement a memory pool that re-uses vectors. This way you evade allocation overhead.
So lets assume you have work like this:
while(true)
create vec
clone vec to vec 2
compute
then you convert to this:
while(true)
vec=stack.pop()
vec2=stack.pop()
compute
stack.push(vec2)
stack.push(vec)