如何在 C# 中为 Matrix 类初始化二维数组

Posted

技术标签:

【中文标题】如何在 C# 中为 Matrix 类初始化二维数组【英文标题】:How to initialize a two dimension array for a Matrix class in C# 【发布时间】:2021-12-17 14:51:36 【问题描述】:

问题

我正在用 C# 编写一个 Matrix 类,我知道这个类需要一个二维数组来存储 Matrix 对象。我的 Matrix 类的构造函数有两个参数,即 Matrix 的 m 和 n 维。我试图在构造函数中分配数组,但我得到了错误 Invalid Rank Specifier。我试过的代码如下。

class Matrix
    
        //make the dimensions private
        private int m,n;

        //The Matrix constructor needs two parameters
        //The row and column dimensions
        //declare the two dimension array
        private int[][] array;
        public Matrix(int m, int n) 
          //assign the array inside the constructor
            array = new int[m][n];
        
        //method to allocate the Matrix
    

我的目标是先用维度初始化数组,以便可以在没有错误的情况下完成分配,谢谢。

 

【问题讨论】:

第一种选择是使用多维数组而不是锯齿状数组,第二种是使用循环分配每个叶子数组 @ChrᴉzremembersMonica,但我只是使用需要存储在该对象中的数组后面的 new 关键字对其进行了初始化 See also here: jagged vs multidimensional @ChrᴉzremembersMonica,打开链接,同样的问题,谢谢。 【参考方案1】:

我觉得你想做的是创建一个多维数组,你可以了解更多关于here的信息。

在您的情况下,这意味着您将创建一个 int[,] 数组:

class Matrix

    //make the dimensions private
    private int m,n;

    //The Matrix constructor needs two parameters
    //The row and column dimensions
    //declare the two dimension array
    private int[,] array;
    public Matrix(int m, int n) 
      //assign the array inside the constructor
        array = new int[m, n];
    
    //method to allocate the Matrix

之后,您可以通过以下方式访问您的值:

public int GetValue(int m, int n) => array[m,n];

同样适用于设置值:

public void SetValue(int m, int n) => array[m,n] = value;

【讨论】:

好的,你可以编辑设置值的方法使用循环,我只是想了解如何执行迭代以实现成功的分配 我在创建一个新的 Matrix 对象后尝试分配,但出现cannot apply indexing with [] to an object of type Matrix 的错误。我试图像这样分配Matrix A = new Matrix(4,4); A[0][0]=2;你能帮我弄清楚这是为什么吗? 如果你想遍历一个多维数组,你可以这样做:for(int i = 0; i <= array.GetUpperBound(0); i++) Console.WriteLine(array[i,0]) 但是如果你想遍历所有维度和所有元素,你可以这样做:for(int i = 0; i < array.GetLength(0); i++) for(int x = 0; x < array.GetLength(1); x++) @RóbertPécz,你检查我的 Matrix 类中的构造函数了吗?构造函数就是一切,我将使用它来初始化类外的数组【参考方案2】:

你实际上有一个锯齿状数组,即数组数组int[][],注意二维数组int[,] p>

要初始化int[][],你必须创建每个内部数组:

 public Matrix(int m, int n) 
   array = new int[m][];         // outer array of size m which

   for (int i = 0; i < n; ++i)   // contains
     array[i] = new int[n];      // arrays of length n 
 

您可以使用 Linq 来缩短语法:

 using System.Linq;

 ...

 public Matrix(int m, int n) 
   array = Enumerable
     .Range(0, m)
     .Select(_ => new int[n])
     .ToArray();
 

编辑:可能的Matrix实现:

  class Matrix 
    private int[][] array;

    public Matrix(int rows, int columns) 
      if (rows <= 0)
        throw new ArgumentOutOfRangeException(nameof(rows));
      if (columns <= 0)
        throw new ArgumentOutOfRangeException(nameof(columns));

      array = Enumerable
        .Range(0, rows)
        .Select(_ => new int[columns])
        .ToArray();
    

    public int RowCount => array.Length;

    public int ColumnCount => array[0].Length;

    public int this[int row, int column] 
      get 
        if (row < 0 || row >= array.Length)
          throw new ArgumentOutOfRangeException(nameof(row));
        if (column < 0 || column >= array[row].Length)
          throw new ArgumentOutOfRangeException(nameof(column));

        return array[row][column];
      
      set 
        if (row < 0 || row >= array.Length)
          throw new ArgumentOutOfRangeException(nameof(row));
        if (column < 0 || column >= array[row].Length)
          throw new ArgumentOutOfRangeException(nameof(column));

        array[row][column] = value;
      
    
  

【讨论】:

什么是锯齿数组? 我正在尝试分配给数组并收到此错误,Cannot apply indexing with [] to an object of type Matrix,我尝试分配给这样的某个索引Matrix A = new Matrix(4,4); A[0][0] @KINYUA TIMOTHY NJIRU:锯齿状数组是一个数组数组:注意内部数组可以有不同的长度:int[][] array = new int[][] new int[] 1, 2, 3, new int[] 4, new int[] 5, 6;跨度> 重新检查我的第一条评论,在创建 4 x 4 数组矩阵后尝试分配时出错 好吧,我的错,我需要访问Matrix对象内部的数组并赋值,我们如何赋值多维数组?【参考方案3】:

我更喜欢对二维数据使用常规的一维数组。比如:

public class MyMatrix<T> 

        public int Width  get; 
        public int Height  get; 
        public T[] Data  get; 
        public MyMatrix(int width, int height)
        
            Width = width;
            Height = height;
            Data = new T[width * height];
        
        public T this[int x, int y]
        
            get => Data[y * Width + x];
            set => Data[y * Width + x] = value;
        


这比典型的二维多维方法有一些优势:

互操作性:多维数组是一个 .Net 概念,并非每种语言都存在,但几乎每种语言都有某种一维数组。 序列化:大多数序列化库处理一维数组,对二维数组的支持比较参差不齐。 性能:有时您只需要遍历所有项目,使用支持的一维数组可能是最快的方法。 避免陷阱:.GetLength() 用于多维数组非常慢,如果您在循环外缓存值,这不是一个大问题,但如果您不知道这一点,或者忘记这一点,则可能是一个问题。

【讨论】:

哇,试试这个,看起来安全且易于实现,在数组中分配某个索引 A[0][0] 时遇到问题,编译器说 cannot apply indexing with [] to an object of type Matrix,我希望你的代码会工作。 什么版本的 .Net 再次运行,在 getter 和 setter 中出现错误,只有特定的 assignment, call, increment, decrement, call can be used as statement @KINYUA TIMOTHY NJIRU 索引的完成方式类似于 [x, y] 而不是 [x][y]。不确定该错误,但表达式主体属性需要 c# 7,但您应该能够只使用常规 setter/getter。 IE。 getreturn Data[y * Width + x]; 你知道你需要编辑你的答案,这样对我来说变得更容易 @KINYUA TIMOTHY NJIRU 示例代码非常好,就像在任何最新版本的 c# 中一样。总体而言,我认为使用该语言的第一个版本使用示例并没有太大帮助,因为它甚至缺少泛型等基本功能。

以上是关于如何在 C# 中为 Matrix 类初始化二维数组的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中初始化动态二维数组

如何在C#中获取多维数组的行/列的长度?

访问 Matrix 类 (C++) 中的二维数组 (Visual Studio 2010)

如何使一个类在 C# 中用作二维数组?

java 如何将二维数组的一列作为参数传进去 求代码

将二维数组映射到 Eigen::Matrix