如何旋转二维字符数组

How to rotate 2D array of characters

我正在尝试将其顺时针旋转 90 度,但效果不如预期。一定是与我不太熟悉的指针有关。

旋转前的输出:

hiivp
nxhxd
tszeg
xdlqo
kwpae

void rotate_right(char **m, int n) {
char **temp = m;
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        m[i][j] = temp[n-1-j][i];
    }
}

}

旋转后的输出:

kxtnk
wdsdx
plzst
aqsdn
entxk

您正在部分覆盖矩阵。

要执行 90° 旋转,让我们考虑正方形的四个角(大写):

HiivP
nxhxd
tszeg
xdlqo
WwpaE

你需要把H放在P的地方,保存P,然后把P放在E的地方,然后是E放在W的地方,最后是W放在H的地方。每次保存覆盖值时都必须完成这四次移位,这将成为下一阶段的新 运行 值。

然后你可以看到每个单元格都是这样一个four-cell班次的一部分:角落编号为1,1是第一个班次。然后你在位置 2 的单元格上工作,然后是位置 3 的单元格,依此类推。

12341
45652
36-63
25654
14321

有奇数边,中心方块不旋转,没有循环数7。经过六个循环,每个循环涉及四个单元格,方块旋转(6*4 = 24,24+1 = 25 ).使用较大的正方形,您可以看到链接每个循环的 x,y 坐标的“定律”。

在 LSerni 的回答的基础上,为了完整性添加一个实现。

假设矩阵如下:

#define STRING_SIZE     (5)

char m[][STRING_SIZE+1] = { "hiivp",
                            "nxhxd",
                            "tszeg",
                            "xdlqo",
                            "kwpae" };

你可以这样定义旋转函数:

char override_and_backup(char* dest, char val)
{
    char tmp = *dest;
    *dest = val;

    return tmp;
}

void rotate_right(char m[][STRING_SIZE+1], int size)
{
    // rotate layer by layer
    for (int layer = 0; layer < (size / 2); ++layer)
    {
        int current_size = size - (2*layer);    // side size of current layer
        int ncycles = current_size - 1;         // number of cycles to complete rotation

        // perform the rotating cycles
        for (int cycle = 0; cycle < ncycles; ++cycle)
        {
            char* first  = &m[layer][layer+cycle];
            char* second = &m[layer+cycle][layer+current_size-1];
            char* third  = &m[layer+current_size-1][layer+current_size-cycle-1];
            char* fourth = &m[layer+current_size-cycle-1][layer];

            char tmp = *fourth;
            tmp = override_and_backup(first, tmp);
            tmp = override_and_backup(second, tmp);
            tmp = override_and_backup(third, tmp);
            override_and_backup(fourth, tmp);
        }
    }
}