2012-04-02 6 views
1

Wenn ich eine Multidimension Zeiger Darstellung eines Gitters haben wie soDrehen Multidimension Zeiger

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

Wie gehe ich über eine Kopie erstellen, die um 90 Grad im Uhrzeigersinn für NxM Raster gedreht wird?

Ich habe versucht, die Höhe als die neue Breite und Breite als neue Höhe mallocation dann die Werte zu transponieren. Dann wollte ich die Werte der Reihe umkehren, aber ich habe es nicht geschafft.

+0

möglich Duplikat [Wie eine Matrix 90 Grad drehen, ohne zusätzlichen Raum mit?] (Http://stackoverflow.com/questions/3488691/how-to-rotate-a-matrix-90-degrees -ohne-irgendeinen-zusätzlichen-Platz zu verwenden) – Vijay

Antwort

4

Tatsächliche Transposition ist mäßig schmerzhaft: Sie müssen jedes Element von "wo es jetzt ist" zu "wo es in der Transposition sein sollte" verschieben. Wenn Sie wirklich eine p zeigt auf die erste von M Zeiger Zeiger zu tun haben, und jede dieser M Zeiger zeigt auf die erste von Nchar s (als ob es eine Reihe von Größe M von Arrays der Größe N von char e):

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

dann müssen Sie einen neuen Zeiger (die ich q nennen), der auf der ersten von N Zeigern, von denen jeder auf die erste von M Punkte char s (Anmerkung: dies ist eine andere Umsetzung, als Sie gefragt für):

 +---+  +---+---+---+ 
q ---> | * | -----> | a | e | i | 
     +---+  +---+---+---+ 
     | * | -- 
     +---+ \ 
     | * |etc \  +---+---+---+ 
     +---+  ---> | b | f | j | 
     | * |etc  +---+---+---+ 
     +---+ 

Wenn Sie jedoch mit relativ ärgerlich Index-Schreiben und alle Cache-Miss Auswirkungen auf Ihre Laufzeit leben können, können Sie einfach zugreifen p[i][j] als p[j][i] oder p[N-1-j][i] usw. zu „vorgeben“, dass die Dinge umgesetzt werden. Dies könnte am einfachsten mit einigen Makros sein:

(Hinweis: keine der oben genannten ist getestet).

+1

+1 für ASCII-Kunst-Zauberei. –

0

Bei Verwendung von Typ char **, da die Lösung mit fester Größe bereits veröffentlicht wurde, dachte ich, ich würde mit einer dynamischen, \ 0-beendeten Lösung klingeln, die mit Arrays unterschiedlicher Größe funktioniert. Wenn es möglich ist, die Arrays zu beenden, können h und w weggelassen werden. Diese Funktion kann das h und w herausfinden. Natürlich kann es geändert werden, um h und w zu unterstützen, aber die Mächte, die das sind, würde ich eher zurück zur Arbeit, die ihr Reich finanziert, anstatt freie Hilfe zu geben.

#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

Wir haben keinen Hinweis darauf, dass 'p 'nullterminiert ist, noch dass' * p' usw. auf nullterminierte Strings zeigen. Es ist durchaus möglich, dass "w" und "h" _ notwendig sind. –

+0

Persönliche Präferenz und Wunsch, anders zu sein, da die nicht abgeschlossene Lösung bereits von jemand anderem bereitgestellt wird. Wie auch immer, es ist trivial, meins zu modifizieren, um h und w zu unterstützen. Entfernen Sie einfach die Längenprüfungen und NULL-Terminatoren. – hellork