更快地将vector元素复制到vector c++的不同结构



我有一个存储表数据的一维整数向量。我想把它转换成一个多维向量(例如,一个由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>>。使用自定义类将2D矩阵映射到1D向量。这样就可以移动原始向量。即使您需要复制,它可能仍然会更快,因为它只进行一次分配+内存占用,而且它对缓存友好:

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

我有一个存储表数据的一维整数向量。我想把它转换成一个多维向量(例如,一个由int向量组成的向量)

既然您坚持性能,正如前面多次提到的那样,最好创建一个类来包装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;
}
}

最新更新