【问题标题】:How to map the indexes of a matrix to a 1-dimensional array (C++)?如何将矩阵的索引映射到一维数组(C++)?
【发布时间】:2012-12-10 12:49:03
【问题描述】:

我有一个 8x8 矩阵,如下所示:

char matrix[8][8];

另外,我有一个包含 64 个元素的数组,如下所示:

char array[64];

然后我将矩阵绘制为表格,并用数字填充单元格,每个数字从左到右,从上到下递增。

如果我在矩阵中有索引 3(列)和 4(行),我知道它对应于数组中位置 35 的元素,正如我在表中看到的那样画。我相信有某种公式可以将矩阵的 2 个索引转换为数组的单个索引,但我不知道它是什么。

有什么想法吗?

【问题讨论】:

  • arr[i*cols+j] 用于等效的 matrix[i][j] 索引,假设您想要行优先排序,cols 是您定义的列宽(在您的示例中,8)。跨度>
  • 我已经尝试过各种简单的计算,比如行*列*8相乘、除法等,但它不起作用。我数学不太好。

标签: c++ c arrays matrix


【解决方案1】:

大多数语言存储多维数组的方式是进行如下转换:

如果 matrix 的大小为 n(行)乘 m(列),并且我们使用“row-major ordering”(我们首先沿行计数),那么:

matrix[ i ][ j ] = array[ i*m + j ].

这里 i 从 0 到 (n-1),j 从 0 到 (m-1)。

所以它就像一个以“m”为底的数字系统。请注意,最后一个维度的大小(此处为行数)无关紧要。


为了从概念上理解,可以考虑一个 (3x5) 矩阵,其中“i”作为行号,“j”作为列号。如果您从i,j = (0,0) --> 0 开始编号。对于 'row-major' 排序(像这样),布局看起来像:

           |-------- 5 ---------|
  Row      ______________________   _ _
   0      |0    1    2    3    4 |   |
   1      |5    6    7    8    9 |   3
   2      |10   11   12   13   14|  _|_
          |______________________|
Column     0    1    2    3    4 

当您沿行移动(即增加列号)时,您只是开始向上计数,因此数组索引为0,1,2...。当您到达第二行时,您已经有 5 条目,因此您从索引 1*5 + 0,1,2... 开始。在第三行,您已经有 2*5 条目,因此索引是 2*5 + 0,1,2...

对于更高维度,这个想法可以推广,即对于 3D matrix L x N x M:

matrix[ i ][ j ][ k ] = array[ i*(N*M) + j*M + k ]

等等。


有关真正好的解释,请参阅:http://www.cplusplus.com/doc/tutorial/arrays/; 或更多技术方面:http://en.wikipedia.org/wiki/Row-major_order

【讨论】:

  • 我不敢相信它是如此简单......非常有用,谢谢。
  • 我很确定当前的描述是正确的(正如下面@user1480848 的回答所描述的 --- 以及 2014 年 3 月 4 日的相应编辑)。如果您不这么认为,请发表评论 - 而不是直接编辑答案。
  • @DilithiumMatrix 的公式不应该是 j + (i * n) 而不是 i + (j * n) 吗?考虑坐标2,3,它应该使用您的矩阵返回13:3 + (2 * 5) = 13。如果我们改用你的公式,我们会得到2 + (3 * 5) = 17。我错过了什么吗?
  • @Mohamad 绝对,谢谢!这也是下面 user1480848 描述的内容......我想我一定是回滚到错误的编辑。 应该现在修复。我希望。
  • 为了确定,因为它并不总是相同的对流,“n”是指行数,“m”是指列数,对吧?
【解决方案2】:

对于行优先排序,我认为matrix[ i ][ j ] = array[ i*n + j ] 的说法是错误的。

偏移量应该是offset = (row * NUMCOLS) + column

你的语句结果是row * NUMROWS + column,这是错误的。

您提供的链接给出了正确的解释。

【讨论】:

  • 您在回应 zhermes 的回答吗?如果是这样,您可能应该只编辑他/她的帖子并进行更正。
【解决方案3】:

这样的?

//columns = amount of columns, x = column, y = row
var calculateIndex = function(columns, x, y){
    return y * columns + x;
};

以下示例将索引转换回 x 和 y 坐标。

//i = index, x = amount of columns, y = amount of rows
var calculateCoordinates = function(index, columns, rows){
    //for each row
    for(var i=0; i<rows; i++){
        //check if the index parameter is in the row
        if(index < (columns * i) + columns && index >= columns * i){
            //return x, y
            return [index - columns * i, i];
        }
    }
    return null;
};

【讨论】:

  • 也许你能解释一下这与 OP 的原始问题有何关系(并回答)?
  • 我应该读得更好一点。它实际上与OP所要求的完全相反。这会将 35,8,8 转换为 3,4。
  • 现在它说明了两种转换:)
  • 虽然我不得不交换行和列以供使用,但这正是我想要的。
猜你喜欢
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2019-03-15
  • 1970-01-01
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多