【问题标题】:How to read a 2-D array and write it into console as a matrix如何读取二维数组并将其作为矩阵写入控制台
【发布时间】:2020-06-17 03:10:42
【问题描述】:

我想读取一个二维数组并将其作为矩阵写入控制台。我的代码如下所示

读取数组

int[][] arr = new int[3][];
for(int i=0;i<3;i++)
{
    arr[i] = Array.ConvertAll(Console.ReadLine().Split(' '),aTemp => Convert.ToInt32(aTemp));
}

将数组作为矩阵写入控制台

for(int i=0;i<arr.GetLength(0);i++)
{
    for(int j=0;j<arr.GetLength(1);j++)
    {
         Console.WriteLine("\t" + arr[i][j]);
    }
}

但是,当我在控制台中输入输入并尝试运行时,我在此处得到一个 Index out of bound 异常

arr.GetLength(1);

然后我尝试用行和列都像这样初始化列 “int[][] arr = 新的 int[3][3];”。

那时另一个错误来了说

排名说明符无效:预期为 ',' 或 ']'

然后我尝试如下初始化数组

"int[,] arr = new int[3,3];"

这次无效的排名说明符错误消失了,但错误出现在读取数组元素的行中,

这个错误可能是由于没有使用arr[i][j] 并读取每个元素。

我只想知道我的初始代码中的错误是什么,我没有得到 GetLength(1) 的值。 以及int[,] arr = new int[3,3];int[][]arr = new int[3][3];有什么区别

还有没有优化的方法来读取像语句这样的二维数组,而不是使用 2 个 for 循环。

我希望问题很清楚。如果有人帮助我解决这个问题,那就太好了。提前致谢!!!

【问题讨论】:

  • 是整数数组还是实数数组?
  • 你知道之前数组的行数吗?

标签: c# arrays matrix optimization multidimensional-array


【解决方案1】:

int[,]multidimensional array

int[][] 是一个jagged array,它是一个数组数组。像这样描述的锯齿状数组没有等级,调用GetLength(rank) 会导致错误,因为它对编译器只有一个技术维度。它只是一个数组,每个元素都填充了另一个数组。

要将锯齿状二维数组写入矩阵,您可以利用string.Join

连接指定数组的元素或数组的成员 集合,在每个元素之间使用指定的分隔符或 会员。

var arr = new [] {new []{1,2,3},new []{4,5,6},new []{7,8,9}};

for(int i = 0; i< arr.Length; i++)
    Console.WriteLine(string.Join(", ",arr[i] ));

输出

1, 2, 3
4, 5, 6
7, 8, 9

或者其他方法

for (var i = 0; i < arr.Length; i++)
{
   for (var j = 0; j < arr[i].Length; j++)
      Console.Write(arr[i][j] + " "); 
   Console.WriteLine();
}

foreach (var t in arr)
{
   foreach (var t1 in t)
      Console.Write(t1 + " ");
    Console.WriteLine();
}

var result = string.Join(Environment.NewLine, arr.Select(x => string.Join(", ", x)));
Console.WriteLine(result);

对于多维二维数组,您可以调用GetLength(rank) 来获取该特定维度的长度

var arr = new [,] {{1,2,3},{4,5,6},{7,8,9}};

for (var i = 0; i < arr.GetLength(0); i++)
{
   for (var j = 0; j < arr.GetLength(1); j++)
      Console.Write(arr[i, j]);
   Console.WriteLine();
}

【讨论】:

    【解决方案2】:

    我同意@TheGeneral 的观点,即定义锯齿状数组有很多优点。我个人喜欢用固定宽度的列显示二维数组数据。

    例如

    static void Main(string[] args)
    {
        var data = new[] { new[] { 1, 2, 3 }, new[] { 4, 5, 6 }, new[] { 7, 8, 9 } };
        var matrix = new MatrixJagged(data);
    
        Console.WriteLine("Matrix =");
        Console.WriteLine(matrix.ToTableFormat(4));
        // Matrix =
        // | 1    2    3 |
        // | 4    5    6 |
        // | 7    8    9 |
    }
    

    这里开始了锯齿数组类,以便能够存储数据、读取数据并将其格式化为表格。

    public class MatrixJagged
    {
        readonly int[][] data;
    
        public MatrixJagged(int[][] data)
        {
            this.data = data;
            this.RowCount = data.Length;
            this.ColumnCount = data.Length > 0 ? data[0].Length : 0;
        }
        public MatrixJagged(int rowCount, int columnCount, int[] array)
        {
            RowCount = rowCount;
            ColumnCount = columnCount;
            this.data = new int[rowCount][];
            int index = 0;
            for (int i = 0; i < rowCount; i++)
            {
                var row = new int[columnCount];
                Array.Copy(array, index, row, 0, columnCount);
                this.data[i] = row;
                index += columnCount;
            }
        }
        public MatrixJagged(int rowCount, int columnCount)
        {
            RowCount = rowCount;
            ColumnCount = columnCount;
            this.data = new int[rowCount][];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = new int[columnCount];
            }
        }
        public ref int this[int row, int column] { get => ref data[row][column]; }
        public int[] GetRow(int row) => data[row];
        public int RowCount { get; }
        public int ColumnCount { get; }
    
        public static MatrixJagged ReadFrom(string path)
        {
            return ReadFrom(File.OpenText(path));
        }
        public static MatrixJagged ReadFrom(StreamReader reader)
        {
            var rows = new List<int[]>();
            while (!reader.EndOfStream)
            {
                var line = reader.ReadLine();
                var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                var row = parts.Select((s) => int.Parse(s)).ToArray();
                rows.Add(row);
            }
            return new MatrixJagged(rows.ToArray());
        }
    
        public string ToTableFormat(int columnWidth, bool withBrackets=true)
        {
            var sb = new StringBuilder();
            for (int i = 0; i < RowCount; i++)
            {
                if (withBrackets) { sb.Append("| "); }
                sb.Append(string.Join(" ", data[i].Select(
                    (x) => x.ToString().PadLeft(columnWidth))));
                if (withBrackets) { sb.Append(" |"); }
                sb.AppendLine();
            }
            return sb.ToString();
        }
    }
    

    【讨论】: