如何将数组从行顺序重写为列顺序?

我有这个双for循环,其中我有行顺序和列顺序数组索引,这应该是性能不好。

for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { /* Column-major order */ d = array_a[col*height +row]; if (d < 0) { d = 0; } /* Row-major order */ /* Map from x=0,y=0 at buttom left corner to 0,0 at top left corner */ array_b[width*(height-1 -row) + col] = d; } } 

是否有关于如何从一个重写到另一个的方法/方法?

当我尝试将最后一个重写为列顺序时,数据会变得歪斜。 不能改写吗?

桑德拉

这永远不会非常快,因为你可能会有很多缓存未命中,你要么必须步进到一个具有大音高的矩阵,要么就是没有逃避。 这里的问题是计算机喜欢连续的内存访问是靠近在一起的,在你的算法中不是这样的情况,由于col 高度项 ,array_a的索引一次跳过高度元素 要修复它你可以切换teh for循环,但是你在array_b中的宽度 (高度为1 -row)项有同样的问题

你可以重写其中一个数组以匹配另一个数组的顺序,但是你会在重写代码中遇到完全相同的问题,所以这取决于你是否需要在这个问题上做多次这样的事情。相同的数据,如果你这样做,那么首先重写一个像Poita_描述的矩阵是有意义的,否则你最好保持算法不变。

由于问题标记为C ++,我将提供一个答案,说明如何使用Boost.Multiarray访问/操作列主矩阵(对于遇到类似问题的其他人可能会有用)。 我认为Boost是C ++标准库的扩展。 如果你不喜欢/使用Boost,请随意忽略这个答案。 🙂

 #include  #include  #include  // Prints the contents of a matrix to standard output template  void printMatrix(const M& matrix) { int height = matrix.shape()[0]; int width = matrix.shape()[1]; for (int row=0; row Matrix; typedef boost::general_storage_order<2> Storage; Matrix matrix( data, boost::extents[height][width], Storage(ordering, ascending) ); // Access source data as if it's row major printMatrix(matrix); std::cout << "\n"; // Transpose source data to an actual row-major matrix // boost::multi_array is row-major by default boost::multi_array matrix2(boost::extents[height][width]); std::copy(matrix.begin(), matrix.end(), matrix2.begin()); printMatrix(matrix2); } 

输出:

 0 1 2 3 4 5 6 7 8 9 10 11 0 1 2 3 4 5 6 7 8 9 10 11 

如您所见,您可以将源数据保留为列主格式,并使用带有自定义存储规范的boost::multi_array_ref来使用matrix[row][col]直接操作数据(就像它是行主要的一样) matrix[row][col]表示法。

如果矩阵通常以行主方式遍历,那么将它转换为实际的行主矩阵可能会更好,如我的示例的最后一部分所示。

所以你想要改变:

 0 1 2 3 4 5 6 7 8 9 10 11 

 0 3 6 9 1 4 7 10 2 5 8 11 

尝试

 for (int i = 0; i < width; ++i) for (int j = 0; j < height; ++j) array_b[ i * height + j ] = array_a[ j * width + i ]; 

如果交换行orrdering很常见,那么编写自己的数组类。

实际上,数据实际上不必移动访问数据的接口需要知道如何访问数据。

 #include  class Matrix { public: Matrix(int width,int height) :data(width,std::vector(height)) ,rowOrder(true) { } int& operator()(int x,int y) { return at(x,y); } int const& operator()(int x,int y) const { return const_cast(*this).at(x,y); } void switchRowOrder() { rowOrder = !rowOrder; } private: int& at(int x,int y) { int& result = (rowOrder) ?data[x][y] // row Order Access :data[y][x]; // col Order Access // Note there is no code to swap around the content of the data internally. return result; } std::vector > data; bool rowOrder; }; 

这不是导致数据偏差的原因吗? 所有负值都被清零:

 if (d < 0) { d = 0; }