2011-10-02 13 views
8

Tengo una matriz de UNA dimensión con N valores, donde N es un cuadrado perfecto. Visualizo esta matriz unidimensional como una matriz bidimensional (aunque no lo es). Por ejemplo, una matriz con valores int Array = { 0,1,2,3,4,5,6,7,8 }Transpose 1 Dimensional Array

Eso es

int *Array = new int [9];                                                  
for (int i = 0 ; i < 9 ; i ++) 
     Array[i] = i; // For example 

Esto se imprime como

0 1 2 
3 4 5 
6 7 8 

Por lo tanto, quiero intercambiar la posición en la matriz unidimensional de tal manera que me da la la transposición de la misma, ...

Por ejemplo ...

0 3 6 
1 4 7 
2 5 8 

Esta es básicamente la misma matriz unidimensional, pero los valores se intercambian de forma que la matriz es ahora int Array = {0,3,6,1,4,7,2,5,8}

Si tuviera que escalar a una gran variedad de dimensiones 1024 * 1024, ¿cómo la lógica es?

Respuesta

18

Con n = sqrt(N), usted podría probar algo tan simple como:

for(int i = 0; i < n; ++i) 
    for(int j = i+1; j < n; ++j) 
     std::swap(Array[n*i + j], Array[n*j + i]); 
+0

Jaja. Esa fue una respuesta súper rápida;) – Legolas

+0

¿Es su matriz una matriz unidimensional? –

8

La operación de transposición realiza swap(v[y][x],v[x][y]) para el triángulo superior o inferior con exclusión de la diagonal de la matriz, (digamos superior).

En un vector unidimensional C vc, v[y][x] corresponde a vc[y*n+x]. Lo que quiere hacer es vc[y*n+x] = vc[x*n+y]

Los elementos que desea intercambiar son aquellos para los que x > y.

que terminan haciendo:

for(int y = 0; y < n; ++y) 
    for(int x = y+1; x < n; ++x) 
     swap(vc[x*n + y], vc[y*n + x]); 

usted podría haber imaginado esto por sí mismo ...

+0

Es cierto. Gracias por una respuesta rápida! ;) – Legolas

0

sin utilizar la función de intercambio. len es la longitud de la matriz.

int i,j; 
    N = sqrt(len);  
    int temp[len]; 
    for(i=0;i<N;i++) 
    { for(j=0;j<N;j++) 
     { 
      temp[j+(i*N)] = a[(j*N)+i]; 
     } 
    } 
1
#include <iostream> 
#include <cmath> 

using namespace std; 

int xyToIndex(const int x, const int y, const int size){ 
    return x + y * size; 
} 

int main(){ 
    int a[] = { 0,1,2,3,4,5,6,7,8 }; 

    const int size = sqrt(sizeof(a)/sizeof(int)); 

    //print only 
    for(int x = 0;x < size; ++x){ 
     for(int y = 0; y < size; ++y) 
      cout << a[xyToIndex(x,y,size)] << " ";; 
     cout << endl; 
    } 
    //make array 
    int b[size*size]; 
    int index = 0; 
    for(int x = 0;x < size; ++x) 
     for(int y = 0; y < size; ++y) 
      b[index++] = a[xyToIndex(x,y,size)]; 

    for(int i = 0; i< size * size ; ++i){ 
     cout << b[i] << " "; 
    } 
} 
1

Usted puede cambiar los valores en la matriz o cambiar la interpretación de las funciones posteriores.

Por ejemplo, en lugar de imprimir a (i, j) puede imprimir a (j, I) e imprimir la transposición.

Habiendo dicho eso, ¿qué es lo que estás tratando de hacer? Si miras a LAPACK y BLAS, sus rutinas toman indicadores que controlan los algoritmos para interpretarlos normalmente o como transpuestos.

0
static unsigned other(unsigned dim0, unsigned dim1, unsigned index) 
{ 

#if 0 
unsigned x0,x1; 
x0 = index % dim0 ; 
x1 = index/dim0 ; 

return x0 * dim1 + x1; 

#else 

unsigned mod,val; 

mod = dim0 * dim1 -1; 
val = (index==mod) ? mod: (dim1*index) % mod; 
return val; 
#endif 
} 

La función anterior devuelve el "otro" índice de índice (el de la matriz transpuesta: = con X e Y intercambiados). dim0 y dim1 son el tamaño "horizontal" y "vertical" de la matriz. La parte # ifdeffed-out es la implementación ingenua. En su caso, usted podría inicializar (o analizar) la matriz de dimensión 1 con:

for (i=0; i < 9; i++) 
    arr[i] = other(3, 3, i); 
Cuestiones relacionadas