【问题标题】:Where's the mistake in my Spiral Matrix algorithm? Size of matrix = input N^2我的螺旋矩阵算法的错误在哪里?矩阵大小 = 输入 N^2
【发布时间】:2014-08-07 02:29:09
【问题描述】:

所以我正在使用 C# 创建一个螺旋矩阵。

螺旋阵列是前 N^2 个自然数的正方形排列,当您绕着阵列的边缘向内旋转时,数字按顺序增加。

例如:

我应该使用算法来执行此操作,但我的最终结果如下所示:

我的代码如下:

    private static void FillMatrix (int[ , ] matrix, int n)
    {
        int positionX = 0;
        int positionY = 0;

        int direction = 0; // The initial direction is "right"
        int stepsCount = n - 1; // stepsCount decrements after 3/2/2/2/2...
        int stepPosition = 0; // 0 steps already performed
        int counter = 1; // counter increments after every turn

        for (int i = 1; i < n * n; i++)
        {
            matrix[positionY, positionX] = i;

            //moving logic:

            if (stepPosition < stepsCount)
            {
                stepPosition++;
            }
            else
            {
                counter++;
                stepPosition = 1;

                if (counter <= 3)
                {
                    direction = (direction + 1) % 4;
                }

                else if (counter % 2 != 0 && counter >= 5 || counter == 4)
                {
                    stepsCount = stepsCount - 1;
                    direction = (direction + 1) % 4;
                }
            }


            // Move to the next cell in the current direction
            switch (direction)
            {
                case 0:
                    // right
                    positionX++;
                    break;
                case 1:
                    // down
                    positionY++;
                    break;
                case 2:
                    // left
                    positionX--;
                    break;
                case 3:
                    // up
                    positionY--;
                    break;
            }
        }
    }

    private static void PrintMatrix (int[ , ] matrix, int n)
    {
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                Console.Write("{0,3}", matrix[i, j]);
            }
            Console.WriteLine();
        }
    }

    static void Main(string[] args)
    {
        int n;

        Console.WriteLine("Please enter N: ");
        bool checkN = int.TryParse(Console.ReadLine(), out n);

        if (checkN)
        {
            int[,] spiralMatrix = new int[n,n];

            FillMatrix(spiralMatrix, n);

            PrintMatrix(spiralMatrix, n);
        }

        Console.ReadKey();
    }
}

}

非常感谢任何帮助!

【问题讨论】:

  • 从 0 开始,而不是 1,以修复明显的一对一问题。输出中的其他数字(20、21、22)由于不正确的宽度/右侧夹紧而出现错位,这会覆盖以前的值并在末尾留下一些未填充的空格。

标签: c# algorithm matrix spiral


【解决方案1】:

您决定何时转弯以及采取多少步的逻辑存在错误,并且比必要的复杂。决定何时转弯的更好方法是检查矩阵本身。用-1 预填充矩阵,然后从左上角开始填充。看到-1,继续直行;如果你到达矩阵的一端,或者下一个位置有-1,然后转一圈。这使您的 stepPosition 和 stepCount 变量变得不必要,并且大大缩短了您的代码。

另一个有用的技巧是右转:保留两个“delta”变量 - dx 和 dy

,而不是将方向保留为单个变量
if (positionX < 0 || positionX == n || positionY < 0 || positionY == N || matrix[positionX][positionY] != -1) {
    int temp = dy;
    dy = dx;
    dx = -temp;
}
positionX += dx;
positionY += dy;

【讨论】:

  • 简单地查找零可能会遇到麻烦。如示例所示,左上角为零。
  • @hk6279 我明白了 - 我没有注意到这个例子,看着 OP 输出中间的错误。我编辑了答案以改用-1。谢谢!
  • 谢谢大家,感谢您的帮助,但问题出在我的算法上,而不是我的方法上。我的错误可能没有让你清楚这个问题,所以我为此道歉。我的工作解决方案在这篇文章中作为您查看的答案。
【解决方案2】:

我已经解决了这个问题。

我的算法有问题。从外向内填充矩阵时,连续行大小的数字模式是N,N-1,N-1,N-2,N-2,N-3,N-3...等等.

例如,在 N 大小为 4 的螺旋矩阵中,模式如下:

4 对。 3下来。 还剩3个。 2 上。 2 对。 1下。 还剩 1 个。

我原本以为模式开始了:

3 对。 3下来。 还剩 3 个。

我忘了再包含一个运动元素,导致算法无法正确填写。

一旦我将条件语句更改为以下代码,就可以得到正确的输出。为了澄清我应该从数组的 0 元素中的 1 开始。对造成的混乱表示歉意。

代码如下:

            int positionX = 0;
            int positionY = 0;

            int direction = 0; // The initial direction is "right"
            int stepsCount = n - 1; // stepsCount decrements after 1/2/2/2/2... turns
            int stepPosition = 1; // 1 steps already performed
            int counter = 0; // counter increments after every change in direction

            for (int i = 1; i < n * n + 1; i++)
            {
                matrix[positionY, positionX] = i;

                //moving logic:

                if (stepPosition <= stepsCount)
                {
                    stepPosition++;
                }
                else
                {
                    counter++;
                    stepPosition = 1;

                    if (counter % 2 != 0)
                    {
                        stepsCount = stepsCount - 1;
                        direction = (direction + 1) % 4;
                    }
                    else if (counter % 2 == 0)
                    {
                        direction = (direction + 1) % 4;
                    }

                }

结果是一种比检查零并根据该规则转向更简单的方法,因为它绝对不会出错。

以下示例结果:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多