Problem
I am writing a Matrix class in C# and I know that this class needs a two dimension array to store the Matrix object. The constructor for my Matrix class takes two parameters, the m and n dimensions of the Matrix. I have tried to assign the array inside the constructor but I get the error that
Invalid Rank Specifier
. The code I tried is listed below.
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
}
My goal is to initialize the array with the dimensions first so that assigning can be done without errors, Thank You.
CodePudding user response:
I feel like what you are trying to do is create a multi dimensional array, which you can learn more about here.
In your case this would mean that you would create an int[,] array as such:
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
}
After that you can access your values through:
public int GetValue(int m, int n) => array[m,n];
And equally for settings values:
public void SetValue(int m, int n) => array[m,n] = value;
CodePudding user response:
You actually have a jagged array, i.e. array of array: int[][]
, note that 2d array is int[,]
To initialize int[][]
you have to create each inner array:
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
}
You can use Linq for shorter syntax:
using System.Linq;
...
public Matrix(int m, int n) {
array = Enumerable
.Range(0, m)
.Select(_ => new int[n])
.ToArray();
}
Edit: Possible Matrix
implementation:
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;
}
}
}
CodePudding user response:
I prefer to use a regular 1D array for 2D data. Something like:
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;
}
}
This has some advantages over the typical 2D Multidimensional approach:
- Interoperability: Multidimensional arrays are a .Net concept that does not exist in every language, but just about every language have some sort of 1D array.
- Serialization: Most serialization libraries handle 1D arrays, support for 2D arrays are more spotty.
- Performance: Sometimes you just need to iterate over all the items, using the backing 1D arrays is probably the fastest way to do this.
- Avoiding pitfals:
.GetLength()
for multidimensional arrays is quite slow, not a large problem if you cache the values outside your loop, but can be a problem if you do not know about this, or forget.