2012-04-02 5 views
1

내가 N × M 개의 그리드에 대한 시계 방향으로 90도 회전 사본을 만들어 가야합니까 어떻게 그렇게회전 다차원 포인터

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

같은 그리드의 다차원 포인터 표현이 있다면?

저는 높이를 새로운 너비로, 그리고 너비를 새 높이로 옮겨서 값을 조 변경하려고했습니다. 그런 다음 행의 값을 뒤집어서 끝내려고했지만이 작업을 수행하지 못했습니다.

+0

중복 가능성 [여분의 공간을 이용하지 않고 매트릭스 90도 회전되다? (http://stackoverflow.com/questions/3488691/how-to-rotate-a-matrix-90-degrees -with-using-any-extra-space) – Vijay

답변

4

실제 이동은 적당히 고통 스럽습니다. "현재 위치"에서 "이동 위치"로 모든 요소를 ​​이동해야합니다. 당신은 정말 M 포인터의 첫 번째에 대한 포인터 p 포인팅을 수행하고 Nchar의 처음에 그 M 포인터 포인트 각각 (가 크기 Nchar의의의 배열의 크기 M의 배열 인 것처럼 사용)하는 경우 : 다음

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

당신이 char의 M의 첫 번째를 가리키는, 각각의 N 포인터의 첫 번째를 가리키는 새로운 포인터 (내가 q를 호출)가 필요합니다 (참고 : 이것은 당신이 물어보다 다른 전위이다 for) :

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

그러나 런타임에 비교적 짜증나는 하위 스크립트 작성 및 캐시 누락 효과로 살아갈 수 있다면 으로 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; 
} 
+0

'p'가 널 종단인지,'* p' 등이 널 종결 문자열을 가르키고 있는지에 대한 정보가 없습니다. 그것의 전적으로 가능한'w'와'h' _areare가 필요합니다. –

+0

종결되지 않은 해결책이 이미 다른 사람에 의해 제공되었으므로 개인의 기호와 욕구가 달라지기를 바랍니다. 어쨌든, h와 w를 지원하도록 광산을 수정하는 것은 사소한 일이다. 그냥 길이 검사와 NULL 종결자를 제거하십시오. – hellork