动态多维数组c#

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态多维数组c#相关的知识,希望对你有一定的参考价值。

我不确定以前是否已经回答过,但这个问题确实具体。我试图在c#中编写一个dungeon生成器,我希望数组的大小是动态的,并且根据输入的大小在控制台中显示为网格。我让数组是动态的,它可以以网格形式显示每个索引,但我无法弄清楚如何使行中的索引数量动态化。这是我到目前为止所拥有的:

        Random rand = new Random();
        int num;
        num = Convert.ToInt32(Console.ReadLine());
        int x = num;
        int y = num;
        int i = x - 1;
        int j = y - 1;
        int[,] dungeon = new int[x,y];

        for(int z = 0; z <= i; z++)
        {
            int a = 0;
            for( a = 0; a <= j; a++)
              {
                  dungeon[a,z] = rand.Next(0,2);
              }

            }
            for (int h = 0; h <= i; h++) 
            {
                if (h == 0)
                {
                    Console.WriteLine("#-#-#-#-#");
                }
            Console.WriteLine("|" + dungeon[h,0] + "|" + dungeon[h,1] + "|" + dungeon[h,2] + "|" + dungeon[h,3] + "|");
            Console.WriteLine("#-#-#-#-#");

请原谅杂乱。它尚未完成。

答案

那么,目前网格总是一个精确的正方形。因为您对两个维度使用相同的值。您是否只想为每个维度使用单独的值?如果是这样,您需要输入中的另一个值。你可以像现在这样做。例如:

int x = Convert.ToInt32(Console.ReadLine());
int y = Convert.ToInt32(Console.ReadLine());

有几点需要注意:

  1. 你不需要你的num变量,你所做的就是立即将它分配给另一个变量,然后再也不要使用num。首先使用您想要的变量。
  2. 作为学术练习,请查看int.TryParse()以及如何使用它的示例。目前,如果输入除整数之外的任何内容,则应用程序将崩溃。使用int.TryParse(),您可以处理该错误情况。
  3. 另外,作为学术练习,请看一下使用嵌套列表而不是二维数组。像List<List<int>>之类的东西。在某些方面,它看起来会更加冗长(re:messy),在其他方面它会更有用。继续从那里开始,尝试将整个数据结构封装到自定义对象中(GridBoard看似合理的名称)。这将允许您将任何杂乱的东西放入类中,然后游戏逻辑可以干净地与该类交互。
另一答案

我希望数组的大小是动态的

因此,如果您对通用集合没有限制,我强烈建议您使用List <>。忽略更好的清理用户输入的方法,使用列表的代码可能如下所示。由于我们使用面向对象语言,因此最好创建表示我们需求的对象(单元格,网格等)。然后创建表示我们需要的那些对象(行,列,值)的属性或方法。

所以我要把你扔到最深处,但这里是我正在使用的参考资料。

Delegates, Anonymous Methods, and Lambda Expressions。 - 关于同一事物的所有不同陈述/抽象的非常好的文章。

Lambda expressions () => - Microsoft Docs。

Lambda expressions in a Query - 如何使用Linq方法和Lambda表达式查询列表。

Func(TResult) - 基本上是另一位代表.​​. C#现在有足够的这些吗?

Generic Classes; MyClass - 泛型的力量!

DotNetFiddle Example

using System;
using System.Collections.Generic;
using System.Linq;

public class Program
{
    public static void Main()
    {
        Random rand = new Random(); 
        int num;
        num = Convert.ToInt32(Console.ReadLine());
        Func<int> valueGenerator = () => { return rand.Next(0,2); };
        var dungeon = new Grid<int>(num, num, valueGenerator);

        foreach(var row in dungeon.Rows)
        {
            // First() - https://msdn.microsoft.com/en-us/library/bb291976(v=vs.110).aspx
            if (row.First().Row == 0)
            {
                Console.WriteLine("#-#-#-#-#");
            }
            // ToArray() - https://msdn.microsoft.com/en-us/library/bb298736(v=vs.110).aspx
            var rowValues = row.Select(r => r.Value.ToString()).ToArray();

            // string.Join() - https://msdn.microsoft.com/en-us/library/57a79xd0(v=vs.110).aspx
            var rowDisplay = string.Join("|", rowValues);

            // $ ie Interpolated Strings - https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interpolated-strings
            Console.WriteLine($"|{rowDisplay}|");
            Console.WriteLine("#-#-#-#-#"); 
        }
    }

    public class Grid<T>
    {
        private int _numberOfRows;
        private int _numberOfColumns;

        // List<> - https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx
        private List<Cell<T>> _cells;

        public Grid(int numberOfRows, int numberOfColumns)
        {
            if (numberOfRows == 0)
                throw new ArgumentOutOfRangeException("numberOfRows must be greater than zero.");
            if (numberOfColumns == 0)
                throw new ArgumentOutOfRangeException("numberOfColumns must be greater than zero.");

            _numberOfRows = numberOfRows;
            _numberOfColumns = numberOfColumns;

            // Enumerable.Range - https://msdn.microsoft.com/en-us/library/system.linq.enumerable.range(v=vs.110).aspx
            _cells = Enumerable.Range(0, _numberOfRows)
                // Select - https://msdn.microsoft.com/en-us/library/bb548891(v=vs.110).aspx
                .Select(r => Enumerable.Range(0, _numberOfColumns)
                        .Select(c => new Cell<T>
                                {
                                    Row = r,
                                    Col = c
                                })
                        // ToList() - https://msdn.microsoft.com/en-us/library/bb342261(v=vs.110).aspx
                        .ToList())
                // - https://msdn.microsoft.com/en-us/library/system.linq.enumerable.selectmany(v=vs.110).aspx
                .SelectMany(c => c)
                .ToList();
        }

        public Grid(int numberOfRows, int numberOfColumns, Func<T> valueGenerator)
        {
            if (numberOfRows == 0)
                throw new ArgumentOutOfRangeException("numberOfRows must be greater than zero.");
            if (numberOfColumns == 0)
                throw new ArgumentOutOfRangeException("numberOfColumns must be greater than zero.");

            _numberOfRows = numberOfRows;
            _numberOfColumns = numberOfColumns;

            _cells = Enumerable.Range(0, _numberOfRows)
                .Select(r => Enumerable.Range(0, _numberOfColumns)
                        .Select(c => new Cell<T>
                                {
                                    Row = r,
                                    Col = c,
                                    Value = valueGenerator()
                                })
                        .ToList())
                .SelectMany(c => c)
                .ToList();
        }

        public IEnumerable<ICell<T>> Cells
        {
            get
            {
                return _cells;
            }
        }

        public IEnumerable<IEnumerable<ICell<T>>> Rows
        {
            get
            {           
                return _cells.GroupBy(c => c.Row)
                    .Select(gs => gs.OrderBy(g => g.Col).ToList())
                    .ToList();
            }
        }

        public IEnumerable<IEnumerable<ICell<T>>> Columns
        {
            get
            {
                return _cells.GroupBy(c => c.Col)
                    .Select(gs => gs.OrderBy(g => g.Row).ToList())
                    .ToList();
            }
        }

        // We expose the Interface because we don't want anyone outside grid modifying
        // Row or Col
        public interface ICell<T>
        {
            int Row { get; }
            int Col { get; }
            T Value { get; set; }
        }

        private class Cell<T> : ICell<T>
        {
            public T Value { get; set; }
            public int Row { get; set; }
            public int Col { get; set; }
        }


    }

}

输出(0和1是随机的......)

4

#-#-#-#-#
|0|0|0|1|
#-#-#-#-#
|1|0|0|1|
#-#-#-#-#
|0|0|1|0|
#-#-#-#-#
|0|1|1|0|
#-#-#-#-#

在所有这些之后你可能会问自己,为什么要使用泛型类Grid?好吧,我怀疑你想要存储在Cell中的唯一东西是int。也许你想存储一个代表各种事物的完整对象......

int Replaced with DungeonCell<>

以上是关于动态多维数组c#的主要内容,如果未能解决你的问题,请参考以下文章

c_cpp Ç与C ++的动态多维数组的建立与释放

正确分配多维数组

动态大小的多维数组的 C++ 解决方法

PHP如何动态为多维数组的子数组分别添加元素

为啥我在 C 中的多维动态分配不起作用?

多维数组如何在内存中格式化?