Search code examples
c++stdvector

Faster way to copy vector elements to different structure of vector C++


I have a one dimension vector of integer that stores table data. Which I want to transform into a multidimensional vector (e.g. a vector of int vectors).

This is what I tried:

std::vector<int> lin_table = {1,2,3,4, 1,2,3,4, 1,2,3,4, 1,2,3,4, 1,2,3,4}
std::vector<std::vector<int>> multi_table;
int num_cols = 4;
for (int column = 0; column < num_cols; column++)
{
   std::vector<int> temp_column;
   for(int element = column; element < lin_table.size(); element += num_cols)
   {
       temp_column.push_back(lin_table.at(element));
   }
   multi_table.push_back(temp_column);
}

This is working fine, but I would like to know if there is any faster way to do it?


Solution

  • I have a one dimension vector of integer that stores table data. Which I want to transform into a multidimensional vector (e.g. a vector of int vectors).

    Since you insist on performance, as already stated many times here before, it is better to create a class that wraps around a std::vector which emulates what a two-dimensional vector would do.

    #include <functional>
    #include <vector>
    
    template <typename T>
    class Vec2DWrapper {
        std::reference_wrapper<std::vector<T>> vec_;
        size_t rows_;
    
    public:
        using value_type = T;
        Vec2DWrapper(std::vector<T>& vec, size_t const rows)
         : vec_(std::ref(vec)), rows_(rows) {
        }
        T& operator()(size_t const x, size_t const y) {
            return vec_.get()[x * rows_ + y];
        }
        std::vector<T>& get_vector() const { return vec_.get(); }
    
    };
    

    Now, you can use it like this:

    #include <iostream>
    
    // ...
    
    int main() {
        std::vector<int> lin_table { 1,2,3,4, 1,2,3,4, 1,2,3,4, 1,2,3,4, 1,2,3,4 };
    
        // Bind the 'lin_table' vector to the class
        Vec2DWrapper<int> vec2d(lin_table, 4);
    
        for (size_t i = 0; i < 4; i++) {
            for (size_t j = 0; j < 5; j++)
                std::cout << vec2d(j, i) << " ";
            std::cout << std::endl;
        }
    }