旋转多维数组

时间:2016-02-28 23:05:47

标签: c# matrix multidimensional-array rotation

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

假设我有一个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#中做到这一点?

2 个答案:

答案 0 :(得分:0)

它让我想起了this hackerrank problem

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

例如,请考虑以下算法:

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

答案 1 :(得分:0)

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

以下代码通过您给出的示例解决您的问题。请注意,此代码仅旋转外圆。例如,如果旋转圆是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;
}