2010-05-23 71 views
21

Cómo rotar una matriz N x N en 90 grados. Quiero que esté en el lugar?¿Cómo rotar una matriz N x N en 90 grados?

+0

duplicados de [¿Cómo girar una matriz de dos dimensiones?] (Http://stackoverflow.com/questions/42519/how-do-you-rotate-a-two-dimensional-array) (el código en esas soluciones generalmente no es C++, pero los algoritmos son lo suficientemente simples como para que la conversión a C++ sea trivial en la mayoría de los casos) –

+2

Eso depende de cómo se almacena la matriz en su estructura de datos. ¿Qué has intentado hasta ahora? –

+0

En sentido horario o antihorario? –

Respuesta

46
for(int i=0; i<n/2; i++) 
    for(int j=0; j<(n+1)/2; j++) 
     cyclic_roll(m[i][j], m[n-1-j][i], m[n-1-i][n-1-j], m[j][n-1-i]); 


void cyclic_roll(int &a, int &b, int &c, int &d) 
{ 
    int temp = a; 
    a = b; 
    b = c; 
    c = d; 
    d = temp; 
} 

Nota no he probado esto , solo compuesto ahora en el acto. Por favor, prueba antes de hacer algo con él.

+0

¿podría explicarme cómo surgieron los índices? –

+3

Explicando los índices ... bueno, piense dónde va la ubicación en (i, j) al girar 90 grados. Solo imagina la foto. (i, j) -> (end-j, i).Tan alto como el original estaba lejos de la izquierda, y tan lejos de la izquierda como del fondo de la matriz. –

+1

Si se gira en sentido antihorario, la asignación es [p] [k] -> a [N-1-k] [p] -> a [N-1-p] [N-1-k] -> a [k] [N-1-p]. Creo que también hay un error en la restricción para i. Debería ser i

-5

Puede crear una segunda matriz y luego copiar la primera en la segunda leyendo row-major en la primera y escribiendo column-major en la segunda.

por lo que sería copiar:

1 2 3 
4 5 6 
7 8 9 

y puedan leer la primera fila y luego escribir una copia de seguridad de partida como:

3 
2 
1 
9

aquí es mi solución: (girar pi/2 hacia la derecha)

  1. hacer la transpuesta de la matriz, (como transposición de matriz)

  2. revertir los elementos de cada fila

    cons int row = 10; 
    cons int col = 10; 
    //transpose 
    for(int r = 0; r < row; r++) { 
        for(int c = r; c < col; c++) { 
        swap(Array[r][c], Array[c][r]); 
        } 
    } 
    //reverse elements on row order 
    for(int r = 0; r < row; r++) { 
        for(int c =0; c < col/2; c++) { 
         swap(Array[r][c], Array[r][col-c-1]) 
        } 
    } 
    

si gira pi/2 en sentido antihorario

  1. transponer la matriz

  2. revertir los elementos en orden de columnas

no probar el código! ¡cualquier sugerencia sería apreciada!

+0

Cada elemento se moverá dos veces (en comparación con 1,25 veces en la respuesta de @Pavel Radzivilovsky), por lo que es menos eficiente. El "aspecto positivo" es que, dado que no es necesario un 'int temp', el requisito de memoria se reduce en los cuatro bytes ... –

+1

de acuerdo con @ Jean-FrançoisCorbett no es tan eficiente como los otros ans. Pero, este es más simple seguro. En realidad, también implementé el mismo algo !! – MalTec

+0

gracias esto simplifica en gran medida la solución –

0

Un completo programa C que ilustra mi enfoque. Esencialmente es algo recurrente. En cada recursión, se rota la capa externa. Deténgase cuando su matriz sea 1x1 o 0x0.

#include <stdio.h> 

int matrix[4][4] = { 
    {11, 12, 13, 14}, 
    {21, 22, 23, 24}, 
    {31, 32, 33, 34}, 
    {41, 42, 43, 44} 
}; 

void print_matrix(int n) 
{ 
    for (int i = 0; i < n; i++) { 
     for (int j = 0; j < n; j++) { 
     printf(" %d ", matrix[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int *get(int offset, int x, int y) 
{ 
    return &matrix[offset + x][offset + y]; 
} 

void transpose(int offset, int n) 
{ 
    if (n > 1) { 
     for (int i = 0; i < n - 1; i++) { 
     int *val1 = get(offset, 0, i); 
     int *val2 = get(offset, i, n - 1); 
     int *val3 = get(offset, n - 1, n - 1 - i); 
     int *val4 = get(offset, n - 1 - i, 0); 

     int temp = *val1; 
     *val1 = *val4; 
     *val4 = *val3; 
     *val3 = *val2; 
     *val2 = temp; 
     } 

     transpose(offset + 1, n - 2); 
    } 
} 

main(int argc, char *argv[]) 
{ 
    print_matrix(4); 
    transpose(0, 4); 
    print_matrix(4); 
    return 0; 
} 
0
//Java version, fully tested 

public class Rotate90degree { 


     public static void reverseElementsRowWise(int[][] matrix) { 
      int n = matrix.length; 
      for(int i = 0; i < n; ++i) { 
       for(int j = 0; j < n/2; ++j) { 
        int temp = matrix[i][n - j - 1]; 
        matrix[i][n - j - 1] = matrix[i][j]; 
        matrix[i][j] = temp; 
       } 
      } 
     } 

     public static void transpose(int[][] matrix) { 
      int n = matrix.length; 
      for(int i = 0; i < n; ++i) { 
       for(int j = i + 1; j < n; ++j) { 
        int temp = matrix[i][j]; 
        matrix[i][j] = matrix[j][i]; 
        matrix[j][i] = temp; 
       } 
      } 
     } 

     public static void rotate90(int[][] matrix) { 
      transpose(matrix); 
      reverseElementsRowWise(matrix); 
     } 

     public static void print(int[][] matrix) { 
      int n = matrix.length; 
      for(int i = 0; i < n; ++i) { 
       for(int j = 0; j < n; ++j) { 
        System.out.print(matrix[i][j]); 
        System.out.print(' '); 
       } 
       System.out.println(); 
      } 
     } 

     public static void main(String[] args) { 
      int[][] matrix = { 
        {1, 2, 3, 4}, 
        {5, 6, 7, 8}, 
        {9, 10, 11, 12}, 
        {13, 14, 15, 16}}; 
      System.out.println("before"); 
      print(matrix); 
      rotate90(matrix); 
      System.out.println("after"); 
      print(matrix); 
     } 
} 
Cuestiones relacionadas