将2D数组填充为菱形

时间:2017-04-20 21:35:20

标签: c# arrays matrix

我希望用一种看起来像enter image description here

的方式用struct填充我的数组

到目前为止我有这个代码:

               `for (int i = 1; i <= n; i++)
                {
                  for (int j = 0; j <=(n - i); j++)
                    //i should fill m[,] here
                  for (int j = 1; j <= i; j++)
                      //i should fill m[,] here
                  for (int k = 1; k < i; k++)
                     //i should fill m[,] here

            }

            for (int i = n - 1; i >= 1; i--)
            {
                  for (int j = 0; j < (n - i); j++)
                        //i should fill m[,] here
                  for (int j = 1; j <= i; j++)
                     //i should fill m[,] here
                  for (int k = 1; k < i; k++)
                      //i should fill m[,] here

            }`

但是我对索引有点困惑。 我该如何采用这段代码?

2 个答案:

答案 0 :(得分:3)

由于它不清楚阵列总是具有5的大小,我假设它具有大小为n,其中n为奇数且n> 1。 0(大小是x y大小,因为我假设你的矩阵是二次的)。然后有几种方法可以达到你想要达到的目标,我会尝试给你一个我想到的目标。

首先我们要考虑数组 - 因为它是最简单的方法,我假设它由布尔值组成(即使你说&#34;我想要用struct&#34; 填充我的数组,但由于我不太清楚你想用它说什么,而且你真的意味着struct,我会放松一下对你而言,因为这不应该是最困难的部分):

var matrix = new bool[n,n];

然后我们必须评估哪些字段必须填写。因此,我们必须认识到一些事情:

  1. 填充字段始终位于其中心
  2. 第一行和最后一行总是有一个填充项
  3. 以下行总是有两个/更少的填充项目,因此偏移量比上一行多一个
  4. 中心线包含大部分物品,是填充物品数量的转折点
  5. 作为开发算法的第一步,我编写了一个函数来用特定数量的字段填充数组的行:

    private static void FillLine(int line, int count, bool[,] matrix)
    {
        //Firstly we have to evaluate the offset:
        var offset = (matrix.GetLength(0) - count) / 2;
        //Then we have to fill the line
        for (var x = offset; x < offset + count; x++)
            matrix[x, line] = true;
    }
    

    现在我们只需要填充整个数组的行:

    public static void FillDiamond(bool[,] matrix)
    {
        var count = 1;
        for (var line = 0; line < matrix.GetLength(1) / 2; line++)
        {
            FillLine(line, count, matrix);
            count += 2;
        }
        FillLine(matrix.GetLength(1) / 2, count, matrix);
        count = 1;
        for (var line = matrix.GetLength(1) - 1; line > matrix.GetLength(1) / 2; line--)
        {
            FillLine(line, count, matrix);
            count += 2;
        }
    }
    

    现在在控制台应用程序中你可以使用它:

    using System;
    
    namespace SO_c
    {
        internal static class Program
        {
            private static void Main()
            {
                while (true)
                {
                    var n = int.Parse(Console.ReadLine());
                    if (n < 1 || n % 2 == 0)
                        continue;
                    var matrix = new bool[n, n];
                    FillDiamond(matrix);
                    for (var y = 0; y < matrix.GetLength(1); y++)
                    {
                        for (var x = 0; x < matrix.GetLength(0); x++)
                            Console.Write(matrix[x, y] ? "█" : " ");
                        Console.WriteLine();
                    }
                }
            }
            private static void FillLine(int line, int count, bool[,] matrix)
            {
                //Firstly we have to evaluate the offset:
                var offset = (matrix.GetLength(0) - count) / 2;
                //Then we have to fill the line
                for (var x = offset; x < offset + count; x++)
                    matrix[x, line] = true;
            }
    
            public static void FillDiamond(bool[,] matrix)
            {
                var count = 1;
                for (var line = 0; line < matrix.GetLength(1) / 2; line++)
                {
                    FillLine(line, count, matrix);
                    count += 2;
                }
                FillLine(matrix.GetLength(1) / 2, count, matrix);
                count = 1;
                for (var line = matrix.GetLength(1) - 1; line > matrix.GetLength(1) / 2; line--)
                {
                    FillLine(line, count, matrix);
                    count += 2;
                }
            }
        }
    }
    

    这可能导致输出:

    Example result

    那就是它!现在你应该得到符合规则的每个矩阵的钻石:)

答案 1 :(得分:0)

一种方法是计算网格的中心并从中间列填充每一行。在每个连续的行中,我们增加我们在中心列每一侧填充的块数,直到我们到达中心行,然后我们减少填充的块数,直到我们到达结束。

要确定任何给定行的中心列每一侧放置的块数,我们可以使用行索引进行计算。

从上到下工作,行索引表示要添加的块数。因此,对于行索引0,我们在中心列的两侧添加0个块,行索引1我们在每一侧添加1个块,直到我们到达中心。

在我们到达中心后,我们希望每次减少块数,这可以通过从总行数中减去行索引来完成。

代码说它更好,我想:

'fun' undeclared (first use in this function)

哦,这是我用来从用户那里获取整数的辅助函数。因为您不必在主代码中进行任何验证,所以保持这种状态非常有用:

private static void Main()
{
    while (true)
    {
        // Get grid size from user and keep it between 1 and the window width
        var gridSize = GetIntFromUser("Enter the size of the grid: ");
        gridSize = Math.Min(Console.WindowWidth - 1, Math.Max(1, gridSize));

        var grid = new bool[gridSize, gridSize];
        var center = (gridSize - 1) / 2;

        // Populate our grid with a diamond pattern
        for (int rowIndex = 0; rowIndex < grid.GetLength(0); rowIndex++)
        {
            // Determine number of blocks to fill based on current row
            var fillAmount = (rowIndex <= center)
                ? rowIndex : grid.GetUpperBound(0) - rowIndex;

            for (int colIndex = 0; colIndex <= fillAmount; colIndex++)
            {
                grid[rowIndex, center - colIndex] = true;
                grid[rowIndex, center + colIndex] = true;
            }
        }

        // Display the final grid to the console
        for (int row = 0; row < grid.GetLength(0); row++)
        {
            for (int col = 0; col < grid.GetLength(1); col++)
            {
                Console.Write(grid[row, col] ? "█" : " ");
            }
            Console.WriteLine();
        }
    }
}

<强>输出

enter image description here