Home > Enterprise >  Create a new empty multi-dimensional jagged vector of same dimensions as another jagged vector
Create a new empty multi-dimensional jagged vector of same dimensions as another jagged vector

Time:05-01

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)
  • Related