2012-04-02 72 views
1

如果我有像这样旋转多维指针

char **p; 
int w; // width (i.e. number of columns) 
int h; // height (i.e. number of rows) 

如何去创建90度顺时针为N×M个网格旋转副本的网格的多维指针的代表性?

我试过mallocing高度作为新的宽度和宽度作为新的高度,然后转置值。然后,我将通过颠倒该行的值来完成,但我没有设法做到这一点。

+0

可能重复[如何旋转矩阵90度,而无需使用任何额外的空间?(http://stackoverflow.com/questions/3488691/how-to-rotate-a-matrix-90-degrees -without-using-any-extra-space) – Vijay 2012-04-02 08:54:08

回答

4

实际换位是中等痛苦的:您必须将每个元素从“现在的位置”移动到“应该换位的位置”。如果你真的有一个指针p指向第一的M指针,而且每个M指针指向第一个Nchar S的(作为如果它的大小charN S的数组的大小M数组):

 +---+  +---+---+---+---+ 
p ---> | * | ----> | a | b | c | d | 
     +---+  +---+---+---+---+ 
     | * | -- 
     +---+ \   +---+---+---+---+ 
     | * | -----------> | i | j | k | l | 
     +---+  \  +---+---+---+---+ 
        \ 
        \ +---+---+---+---+ 
        --> | e | f | g | h | 
         +---+---+---+---+ 

,那么你需要一个新的指针(我会打电话给q)指向前N个指针,每个指向第一个M的char秒(注:这是一个不同的换位比你问for):

 +---+  +---+---+---+ 
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为ASCII艺术魔法。 – 2012-04-02 08:54:39

0

当使用char **类型时,由于固定大小的解决方案已经发布,我以为我会用一个动态的,终止的解决方案与各种大小的数组一起工作。如果可以终止数组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; 
} 
+0

我们没有任何迹象表明'p'是空终止的,也没有'* p'等指向空终止的字符串。它完全有可能需要'w'和'h'。 – 2012-04-02 15:27:28

+0

个人喜好和愿望有所不同,因为未终止的解决方案已由其他人提供。无论如何,修改我的支持h和w是微不足道的。只要删除长度检查和NULL终止符。 – hellork 2012-04-03 05:59:35