【问题标题】:Rotate parts of multidimensional array旋转多维数组的部分
【发布时间】:2016-06-11 21:27:25
【问题描述】:

我需要能够通过声明范围和方向来旋转多维数组的一部分。

假设我有一个 int 数组:

[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]

如果我的范围从 [2,2] 到 [3,3] 并且顺时针旋转,我会得到:

[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 15, 11]
[13, 14, 16, 12]

如果我将范围 [0,1] 应用到 [2,3] 并逆时针旋转,我会得到:

[1, 2, 3, 4]
[7, 15, 16, 8]
[6, 10, 14, 11]
[5, 9, 13, 12]

数组将始终是一个矩阵 NxN (2*2,3*3,4*4..)。只是旋转矩阵不是问题,但我在矩阵内只使用一部分时遇到问题。我将如何在 C# 中执行此操作?

【问题讨论】:

    标签: c# matrix multidimensional-array rotation


    【解决方案1】:

    您需要复制一些行并将它们与列交换。在某些情况下,您可能需要反转它们。

    下面的代码通过您提供的示例解决了您的问题。请注意,此代码仅旋转外圈。例如,如果旋转圈是 4x4,则内圈 2x2 将不会旋转。但你应该明白。

    static void Main(string[] args)
    {
        int[,] array = new int[4, 4]
        {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 16}
        };
    
        Rotate(array, 2, 2, 3, 3, true);
        Rotate(array, 1, 0, 3, 2, false);
    
        for (int i = 0; i < array.GetLength(0); i++)
        {
            for (int j = 0; j < array.GetLength(1); j++)
            {
                Console.Write(array[i, j] + "  ");
            }
            Console.WriteLine();
        }
    }
    
    private static void Rotate(int[,] array, int x1, int y1, int x2, int y2, bool clockwise)
    {
        int[] r1 = CopyFromRow(array, x1, y1, x2 - x1 + 1);
        int[] r2 = CopyFromRow(array, x2, y1, x2 - x1 + 1);
    
        int[] c1 = CopyFromColumn(array, x1, y1, y2 - y1 + 1);
        int[] c2 = CopyFromColumn(array, x1, y2, y2 - y1 + 1);
    
        if (clockwise)
        {
            Array.Reverse(c1);
            Array.Reverse(c2);
    
            CopyToColumn(array, r1, x1, y2);
            CopyToColumn(array, r2, x1, y1);
    
            CopyToRow(array, c1, x1, y1);
            CopyToRow(array, c2, x2, y1);
        }
        else
        {
            Array.Reverse(r1);
            Array.Reverse(r2);
    
            CopyToColumn(array, r1, x1, y1);
            CopyToColumn(array, r2, x1, y2);
    
            CopyToRow(array, c1, x2, y1);
            CopyToRow(array, c2, x1, y1);
        }
    }
    
    private static void CopyToColumn(int[,] array, int[] row, int x1, int y1)
    {
        for (int i = 0; i < row.Length; i++)
        {
            array[x1 + i, y1] = row[i];
        }
    }
    
    private static void CopyToRow(int[,] array, int[] col, int x1, int y1)
    {
        for (int i = 0; i < col.Length; i++)
        {
            array[x1, y1 + i] = col[i];
        }
    }
    
    
    private static int[] CopyFromColumn(int[,] array, int x1, int y1, int length)
    {
        int[] row = new int[length];
    
        for (int i = 0; i < length; i++)
        {
            row[i] = array[x1 + i, y1];
        }
    
        return row;
    }
    
    private static int[] CopyFromRow(int[,] array, int x1, int y1, int length)
    {
        int[] col = new int[length];
    
        for (int i = 0; i < length; i++)
        {
            col[i] = array[x1, y1 + i];
        }
    
        return col;
    }
    

    【讨论】:

      【解决方案2】:

      这让我想起了this hackerrank problem

      我不知道你的具体问题是什么 - 你可以把这个子矩阵作为一个独立的对象,然后旋转它。

      例如考虑以下算法:

      1. 将您的矩阵视为一组'circuits'
      2. 将这些'circuits' 一个接一个。
      3. 为每个电路应用旋转 - 不要忘记检查您是否number of rotations% circuit perimeter = 0(在这种情况下旋转是不变的)
      4. 对于 'circuit' 中的每个整数,只需计算它的新 position(矩阵索引的一些简单数学运算)。

      在您的子矩阵的所有电路都旋转后,您就得到了结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-13
        • 2014-11-23
        • 2023-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-05
        相关资源
        最近更新 更多