如何将长度为9倍数的数组按3×3单元规则转换为矩阵?
数组转3×3单元矩阵的索引计算(C#)
问题描述
给定一个长度为N(N是9的倍数)的数组,需要将其转换为宽度W、高度H均为3的倍数的矩阵。矩阵由3×3的单元块构建:数组前9个元素填充第一个3×3块,接下来9个元素填充第二个3×3块,以此类推;块在矩阵中按行优先排列,每个块内部也按行优先填充。
示例:54个元素的数组转换为宽度9、高度6的矩阵,排列如下:
1, 2, 3, 10, 11, 12, 19, 20, 21, 4, 5, 6, 13, 14, 15, 22, 23, 24, 7, 8, 9, 16, 17, 18, 25, 26, 27, 28, 29, 30, 37, 38, 39, 46, 47, 48, 31, 32, 33, 40, 41, 42, 49, 50, 51, 34, 35, 36, 43, 44, 45, 52, 53, 54,
索引计算推导
要得到数组索引i对应的矩阵索引matIndex,可以分步骤拆解:
- 确定元素所属的3×3块:每个块包含9个元素,块索引为
blockIndex = i / 9 - 确定块在矩阵中的位置:
- 矩阵每行包含的块数:
blocksPerRow = W / 3 - 块所在的矩阵行:
blockRow = blockIndex / blocksPerRow - 块所在的矩阵列:
blockCol = blockIndex % blocksPerRow
- 矩阵每行包含的块数:
- 确定元素在块内的位置:
- 块内的相对索引:
innerIdx = i % 9 - 块内的行偏移:
innerRow = innerIdx / 3 - 块内的列偏移:
innerCol = innerIdx % 3
- 块内的相对索引:
- 计算矩阵的行列索引:
- 矩阵行号:
matRow = blockRow * 3 + innerRow - 矩阵列号:
matCol = blockCol * 3 + innerCol
- 矩阵行号:
- 最终矩阵索引:
matIndex = matRow * W + matCol
C#代码实现
将上述推导代入代码,可分步骤计算或合并为单行表达式:
分步计算版(可读性更强)
var arr = new[] {1,2,3,...,54}; int W = 9; // 矩阵宽度,需为3的倍数 var mat = new int[arr.Length]; for (int i = 0; i < arr.Length; i++) { int blockIndex = i / 9; int blocksPerRow = W / 3; int blockRow = blockIndex / blocksPerRow; int blockCol = blockIndex % blocksPerRow; int innerIdx = i % 9; int innerRow = innerIdx / 3; int innerCol = innerIdx % 3; int matRow = blockRow * 3 + innerRow; int matCol = blockCol * 3 + innerCol; var matIndex = matRow * W + matCol; mat[matIndex] = arr[i]; }
单行简化版
var arr = new[] {1,2,3,...,54}; int W = 9; var mat = new int[arr.Length]; for (int i = 0; i < arr.Length; i++) { var matIndex = ((i/9)/(W/3)*3 + (i%9)/3)*W + ((i/9)%(W/3)*3 + (i%9)%3); mat[matIndex] = arr[i]; }
内容的提问来源于stack exchange,提问作者codeDom
相关产品推荐
相关产品推荐

