如何为N维矩阵的每个元素赋值?(C#/Unity场景)
关于N维矩阵通用赋值方法的实现求助
背景与现有实现
近期我研究将矩阵用于游戏NPC移动坐标映射,进而探索多维矩阵,已在Unity中实现3D矩阵元素赋值逻辑,代码如下:
public class MatrixUnit { public int length; public int width; public int height; public void Maping(int x, int y, int z) { this.length = x; this.width = y; this.height = z; } } public class MatrixManager : MonoBehaviour { public MatrixUnit[,,] Matrix = new MatrixUnit[12, 14, 2]; public void CreateMatrix() { for (int i = 0; i < Matrix.GetLength(0); i++) { for (int j = 0; j < Matrix.GetLength(1); j++) { for (int k = 0; k < Matrix.GetLength(2); k++) { Matrix[i, j, k] = new MatrixUnit(); } } } } public void MatrixMapStart() { for (int i = 0; i < Matrix.GetLength(0); i++) { for (int j = 0; j < Matrix.GetLength(1); j++) { for (int k = 0; k < Matrix.GetLength(2); k++) { if (Matrix[i, j, k] != null) { Matrix[i, j, k].Maping(i, j, k); Debug.Log("Element " + ((i * Matrix.GetLength(1) * Matrix.GetLength(2)) + (j * Matrix.GetLength(2)) + k + 1) + " is in the position " + Matrix[i, j, k].length + ", " + Matrix[i, j, k].width + ", " + Matrix[i, j, k].height); } } } } } void Start() { CreateMatrix(); MatrixMapStart(); } }
我发现维度增加需要对应增加嵌套for循环,希望实现一个仅接收N维矩阵即可完成赋值的通用方法。经大学教授提示学习递归,但尚未找到可行方案。我已尝试分析2D矩阵的逻辑(代码如下),但仍未突破:
public class Item { public int value; } public Item[,] Matrix2D = new Item[5,12]; public void CreateMatrix2D() { for (int i = 0; i < Matrix2D.GetLength(0); i++) { for (int j = 0; j < Matrix2D.GetLength(1); j++) { Matrix2D[i, j] = new Item(); } } } public void Map() { for (int i = 0;i < Matrix2D.GetLength(0);i++) { for (int j = 0;j < Matrix2D.GetLength(1);j++) { Matrix2D[i, j].value = ((i * Matrix2D.GetLength(0)) + j); } } }
注:我通过类实现矩阵是为了后续扩展更多属性,而非仅赋值序号。
通用N维矩阵赋值的实现思路(基于C#)
核心逻辑:递归遍历多维索引
利用C#中所有多维数组都继承自Array类的特性,结合递归实现任意维度的遍历与赋值:
- 参数统一用Array类型:让通用方法接收
Array类型参数,兼容任意维度的矩阵,无需为不同维度重载方法。 - 维护索引数组:用一个整数数组记录当前遍历到的各维度索引,递归时逐层填充这个数组。
- 递归终止条件:当索引数组的长度等于矩阵的维度数时,说明已定位到具体元素,执行创建实例、赋值坐标的操作。
- 逐层递归遍历:对当前维度的每个索引值,填充到索引数组中,然后递归进入下一个维度,直到完成所有维度的遍历。
代码示例
以下是适配你需求的通用实现,包含矩阵实例创建和坐标映射的递归方法:
public class MatrixUnit { // 用数组存储各维度坐标,适配任意维度扩展 public int[] Coordinates; public void Maping(int[] coords) { Coordinates = coords.Clone() as int[]; } } public class MatrixManager : MonoBehaviour { // 示例:4维矩阵 public Array Matrix4D = Array.CreateInstance(typeof(MatrixUnit), 3, 4, 2, 5); void Start() { CreateNMatrix(Matrix4D); MapNMatrix(Matrix4D); } /// <summary> /// 通用创建N维矩阵实例 /// </summary> /// <param name="matrix">目标多维数组</param> public void CreateNMatrix(Array matrix) { // 初始化索引数组,长度等于矩阵维度 int[] indices = new int[matrix.Rank]; RecursiveCreate(matrix, indices, 0); } private void RecursiveCreate(Array matrix, int[] indices, int currentDimension) { // 递归终止:已处理完所有维度,创建实例 if (currentDimension == matrix.Rank) { matrix.SetValue(new MatrixUnit(), indices); return; } // 遍历当前维度的所有索引 int dimensionLength = matrix.GetLength(currentDimension); for (int i = 0; i < dimensionLength; i++) { indices[currentDimension] = i; // 递归处理下一个维度 RecursiveCreate(matrix, indices, currentDimension + 1); } } /// <summary> /// 通用N维矩阵坐标映射 /// </summary> /// <param name="matrix">目标多维数组</param> public void MapNMatrix(Array matrix) { int[] indices = new int[matrix.Rank]; RecursiveMap(matrix, indices, 0); } private void RecursiveMap(Array matrix, int[] indices, int currentDimension) { if (currentDimension == matrix.Rank) { MatrixUnit unit = matrix.GetValue(indices) as MatrixUnit; if (unit != null) { unit.Maping(indices); // 计算元素序号(可选) int elementIndex = CalculateElementIndex(matrix, indices); Debug.Log($"Element {elementIndex + 1} is in position: {string.Join(", ", unit.Coordinates)}"); } return; } int dimensionLength = matrix.GetLength(currentDimension); for (int i = 0; i < dimensionLength; i++) { indices[currentDimension] = i; RecursiveMap(matrix, indices, currentDimension + 1); } } /// <summary> /// 计算多维索引对应的线性序号 /// </summary> private int CalculateElementIndex(Array matrix, int[] indices) { int index = 0; int multiplier = 1; // 从最后一个维度往前计算 for (int dim = matrix.Rank - 1; dim >= 0; dim--) { index += indices[dim] * multiplier; multiplier *= matrix.GetLength(dim); } return index; } }
关键说明
- 把
MatrixUnit的坐标从单独的length/width/height改成数组Coordinates,适配任意维度的扩展需求。 - 递归方法通过
currentDimension参数跟踪当前处理的维度,避免嵌套循环的限制。 CalculateElementIndex方法通用计算任意多维索引对应的线性序号,替代原3D代码中的硬计算逻辑。
内容的提问来源于stack exchange,提问作者Megalomaniacal Programmer
相关产品推荐
相关产品推荐

