2012-04-02 93 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