如何旋转二维字符数组
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);
}
}
}
我正在尝试将其顺时针旋转 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);
}
}
}