将向量元素复制到向量 C++ 的不同结构的更快方法

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

我有一个存储 table 数据的一维整数向量。我想将其转换为多维向量(例如 int 向量的向量)。

这是我试过的:

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);
}

这工作正常,但我想知道是否有更快的方法?

不要使用 vector<vector<int>>。使用自定义 class 将二维矩阵映射到一维向量。这样你就可以移动原始向量。即使你需要复制,它可能仍然会更快,因为它只进行一次分配+memcpy,而且它是缓存友好的:

#include <vector>
#include <cstdio>

template <class Vector>
class Vec2D {
private:
    std::size_t mWidth = 0, mHeight = 0;
    Vector mData;

public:
    Vec2D(int height, int width) 
        : mWidth(width)
        , mHeight(height)
        , mData(width * height)
    {}

    Vec2D(int height, Vector vec) noexcept
        : mWidth(vec.size() / height)
        , mHeight(height)
        , mData(std::move(vec))
    {}

    auto& get(std::size_t row, std::size_t col) noexcept {
        return mData[mHeight * col + row]; // mix is intentional
    }

    auto& get(std::size_t row, std::size_t col) const noexcept {
        return mData[mHeight * col + row]; // mix is intentional
    }

    auto width() const noexcept {
        return mWidth;
    }

    auto height() const noexcept {
        return mHeight;
    }
};

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};

    Vec2D v2d{4, std::move(lin_table)};

    for (size_t i = 0; i < v2d.height(); ++i) {
        for (size_t j = 0; j < v2d.width(); ++j) {
            std::printf("%d ", v2d.get(i, j));
        }
        std::putchar('\n');
    }
}

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).

由于您坚持性能,正如之前在这里多次声明的那样,最好创建一个 class 环绕 std::vector 模拟 二维向量会做什么。

#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(); }

};

现在,您可以像这样使用它:

#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;
    }
}