我已经困惑了这个不常见的任务,花了好几天来找出合适的算法。假设我有2D数组:
int[][] jagged = new int[4][];
jagged[0] = new int[4] { 1, 2, 3, 4 };
jagged[1] = new int[4] { 5, 6, 7, 8 };
jagged[2] = new int[4] { 9, 10, 11, 12 };
jagged[3] = new int[4] { 13, 14, 15, 16 };
如何以逆时针方向旋转此矩阵,如下所示?
1 2 3 4 2 3 4 8 3 4 8 12
5 6 7 8 --> 1 7 11 12 --> 2 11 10 16
9 10 11 12 5 6 10 16 1 7 6 15
13 14 15 16 9 13 14 15 5 9 13 14
2D数组可以有各种尺寸。我指的是2x3或3x4。
我尝试使用以下算法,但它只旋转90度:
int [,] newArray = new int[4,4];
for (int i=3;i>=0;--i)
{
for (int j=0;j<4;++j)
{
newArray[j,3-i] = array[i,j];
}
}
如果我改变增量,那么它确实没有给我任何东西。也许有另一种解决方案吗?
答案 0 :(得分:2)
假设每个&#34; square&#34;阵列的独立旋转 您可以使用以下代码段:
const int ArraySize = 4;
int[,] array =
{
{ 2, 3, 4, 8 },
{ 1, 7, 11, 12 },
{ 5, 6, 10, 16 },
{ 9, 13, 14, 15 }
};
for (int r = (ArraySize - 1) / 2; r >= 0; r--)
{
int start = r;
int end = ArraySize - r - 1;
int saveTopLeft = array[start, start];
// Top
for (int i = start; i <= end - 1; i++)
array[start, i] = array[start, i + 1];
// Right
for (int i = start; i <= end - 1; i++)
array[i, end] = array[i + 1, end];
// Bottom
for (int i = end; i >= start + 1; i--)
array[end, i] = array[end, i - 1];
// Left
for (int i = end; i >= start + 2; i--)
array[i, start] = array[i - 1, start];
// Saved element
array[start + 1, start] = saveTopLeft;
}
答案 1 :(得分:1)
我知道这个问题已经回答,但我想为nxm
的一般矩阵做这个问题。它考虑了矩阵只有一列或一行的极端情况。
public static void Rotate(int[,] matrix)
{
// Specific cases when matrix has one only row or column
if (matrix.GetLength(0) == 1 || matrix.GetLength(1) == 1)
RotateOneRowOrColumn(matrix);
else
{
int min = Math.Min(matrix.GetLength(0), matrix.GetLength(1)),
b = min / 2, r = min % 2;
for (int d = 0; d < b + r; d++)
{
int bkp = matrix[d, d];
ShiftRow(matrix, d, d, matrix.GetLength(1) - d - 1, true);
ShiftColumn(matrix, matrix.GetLength(1) - d - 1, d, matrix.GetLength(0) - d - 1, false);
ShiftRow(matrix, matrix.GetLength(0) - d - 1, d, matrix.GetLength(1) - d - 1, false);
ShiftColumn(matrix, d, d + 1, matrix.GetLength(0) - d - 1, true);
if (matrix.GetLength(0) - 2 * d - 1 >= 1)
matrix[d + 1, d] = bkp;
}
}
}
private static void RotateOneRowOrColumn(int[,] matrix)
{
bool isRow = matrix.GetLength(0) == 1;
int s = 0, e = (isRow ? matrix.GetLength(1) : matrix.GetLength(0)) - 1;
while (s < e)
{
if (isRow)
Swap(matrix, 0, s, 0, e);
else
Swap(matrix, s, 0, e, 0);
s++; e--;
}
}
public static void Swap(int[,] matrix, int from_x, int from_y, int to_x, int to_y)
{
//It doesn't verifies whether the indices are correct or not
int bkp = matrix[to_x, to_y];
matrix[to_x, to_y] = matrix[from_x, from_y];
matrix[from_x, from_y] = bkp;
}
public static void ShiftColumn(int[,] matrix, int col, int start, int end, bool down)
{
for (int i = down ? end - 1 : start + 1; (down && i >= start) || (!down && i <= end); i += down ? -1 : 1)
{ matrix[i + (down ? 1 : -1), col] = matrix[i, col]; }
}
public static void ShiftRow(int[,] matrix, int row, int start, int end, bool left)
{
for (int j = left ? start + 1 : end - 1; (left && j <= end) || (!left && j >= start); j += (left ? 1 : -1))
{ matrix[row, j + (left ? -1 : 1)] = matrix[row, j]; }
}