将向量元素复制到向量 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;
}
}
我有一个存储 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;
}
}