如果我有一个像这样的网格的多维指针表示
char **p;
int w; // width (i.e. number of columns)
int h; // height (i.e. number of rows)
如何为NxM网格创建一个顺时针旋转90度的副本?
我尝试将高度作为新宽度进行malloc,并将宽度作为新高度,然后转置值。然后我将通过反转行的值来完成,但我没有设法做到这一点。
答案 0 :(得分:4)
实际换位是中度痛苦的:你必须将每个元素从“现在的位置”移动到“它应该在换位中”。如果你确实有一个指向p
指针的指针M
,那么每个M
指针指向N
char
的第一个指针(好像它是M
个N
大小char
数组 +---+ +---+---+---+---+
p ---> | * | ----> | a | b | c | d |
+---+ +---+---+---+---+
| * | --
+---+ \ +---+---+---+---+
| * | -----------> | i | j | k | l |
+---+ \ +---+---+---+---+
\
\ +---+---+---+---+
--> | e | f | g | h |
+---+---+---+---+
的数组:
q
然后你需要一个新的指针(我将称之为char
)指向N个指针中的第一个,每个指针都指向M +---+ +---+---+---+
q ---> | * | -----> | a | e | i |
+---+ +---+---+---+
| * | --
+---+ \
| * |etc \ +---+---+---+
+---+ ---> | b | f | j |
| * |etc +---+---+---+
+---+
的第一个(注意:这是一个不同的转换比你要求的):
p[i][j]
但是,如果您可以使用相对恼人的下标写入和运行时的任何缓存未命中效果,您只需访问p[j][i]
p[N-1-j][i]
或#define ORIENTATION_A(p, M, N, i, j) ((p)[i][j])
#define ORIENTATION_B(p, M, N, i, j) ((p)[(N)-1-(j)][i])
/* etc */
等, “假装”事情被转换。对于某些宏来说,这可能是最简单的:
{{1}}
(注意:以上都没有经过测试)。
答案 1 :(得分:0)
当使用char **类型时,由于已经发布了固定大小的解决方案,我认为我会使用动态的\ 0终止解决方案来处理各种大小的数组。如果可以终止数组h,则可以省略w。这个函数可以找出h和w。当然,它可能会被改为支持h和w,但是那些力量我宁愿回到工作岗位为他们的帝国提供资金而不是提供免费帮助。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
/* rotate_array
w h
**p _______ **q ___
|A B C D|\0 ===> |E A|\0
h |E F G H|\0 ==> |F B|\0 w
NULL----- |G C|\0
|H D|\0
NULL-
*/
char **rotate_array(char **p) {
int w,h,hh;
char **q;
for (w=0;p[0][w];w++);
for (hh=0;p[hh];hh++);
if (!(q = malloc(w * sizeof q))) {
perror ("malloc");
exit (1);
} fprintf (stderr,"made it\n");
for (w=0;p[0][w];w++) {
if (!(q[w] = malloc(hh))) {
perror ("malloc");
exit (1);
} for (h=0;h<hh;h++) {
q[w][hh-h-1] = p[h][w];
} q[w][h]='\0';
} q[w]=NULL;
return q;
} void free_array(char **p) {
int h;
for (h=0;p[h];h++) {
free (p[h]);
} free (p);
}
// main
int main (int argc, char **argv) {
int h;
char *p[3]={"ABCD","EFGH",NULL};
char **q;
for (h=0;p[h];h++) {
printf ("%s\n",p[h]);
} printf ("\n");
q = rotate_array (p);
for (h=0;q[h];h++) {
printf ("%s\n",q[h]);
} free_array (q);
return 0;
}