2012-04-02 10 views
1

私はN×Mのグリッドのために時計回りに90度回転させたコピーを作成する行くにはどうすればよいので回し多次元ポインタ

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

のようなグリッドの多次元ポインタ表現を持っている場合は?

私は新しい幅として高さをmallocし、値を転置して新しい高さとして幅を試しました。その後、私は行の値を逆にして終了するつもりでしたが、私はこれを行うことはできませんでした。

+0

の可能複製[すべての余分なスペースを使用せずに行列を90度回転させる方法は?](http://stackoverflow.com/questions/3488691/how-to-rotate-a-matrix-90-degrees -with-using-any-extra-space) – Vijay

答えて

4

実際の転位は中程度の痛みを伴います。すべての要素を「現在の位置」から「転位の位置」に移動する必要があります。あなたは本当にNchar S(それはchar SのサイズNの配列のサイズMの配列だかのように使用される)の最初にMポインタの最初を指すポインタp、およびそれらのMポインタの各点を持っている場合:その後、

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

はあなたがchar S Mの最初を指し、それぞれが、Nポインタの最初を指す新しいポインタ(私はqを呼び出します)必要があります(注:これはあなたが尋ねたよりも異なる転置でありますfor):

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

しかし、実行時に比較的厄介なサブスクリプト書き込みやキャッシュミスの影響を受けて暮らすことができる場合は、または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アートウィザード。 –

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; 
} 
+0

'p'がヌルで終了しているか、' * p'でヌルで終了している文字列を指しているということはありません。 'w'と' h'_が必要です。 –

+0

未解決の解決策が既に他の人によって提供されているため、個人的な好みと異なることが望まれます。とにかく、hとwをサポートするように鉱山を変更するのは簡単です。長さチェックとNULLターミネータを削除するだけです。 – hellork