2011-10-02 12 views
8

Mam więc JEDNĄ tablicę wymiarową z N wartościami, gdzie N to idealny kwadrat. Wizualizuję tę jednowymiarową tablicę jako tablicę dwuwymiarową (choć tak nie jest). Na przykład, tablica z wartościami int Array = { 0,1,2,3,4,5,6,7,8 }Transpozycja 1 tablica wymiarowa

To

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

ten jest drukowany jako

0 1 2 
3 4 5 
6 7 8 

So, chcę zamienić pozycję w jednej tablicy wymiarowe takie, że dostanę przetransponuj go, ...

Na przykład ...

0 3 6 
1 4 7 
2 5 8 

Jest to w zasadzie ta sama tablica wymiarowa, ale wartości są zamienione tak, że tablica jest teraz int Array = {0,3,6,1,4,7,2,5,8}

Gdybym go skalować do tablicy o wymiarze 1024 * 1024, jak będzie logika być?

Odpowiedz

18

Z n = sqrt(N), można po prostu spróbować czegoś prostego, takich jak:

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

Haha. To była super szybka odpowiedź;) – Legolas

+0

Czy twój Array to jedna tablica szumna? –

8

Operacja transpozycji wykonuje swap(v[y][x],v[x][y]) dla górnego lub dolnego trójkąta wyłączeniem przekątnej matrycy (powiedzmy górny).

W wektorze jednowymiarowym C vc, v[y][x] odpowiada vc[y*n+x]. Więc chcesz wykonać: vc[y*n+x] = vc[x*n+y]

Elementy, które chcesz zamienić, to te, dla których x > y.

skończyć się robi:

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

Mogłeś zorientowaliśmy się ...

+0

Prawda. Dzięki za szybką odpowiedź! ;) – Legolas

0

bez używania funkcji wymiany. len jest długością tablicy.

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

Można też zamienić wartości w macierzy lub zamienić interpretację w późniejszych funkcji.

Na przykład, zamiast drukowania (i, j) można wydrukować (j, I) i wydrukować trans.

W związku z tym, co exaclty próbujesz zrobić? Jeśli spojrzysz na LAPACK i BLAS, ich procedury przyjmują flagi, które kontrolują algorytmy w celu ich normalnej interpretacji lub transpozycji.

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 
} 

Powyższa funkcja zwraca "inny" indeks indeksu (ten w transponowanej macierzy: = z zamienionymi na xiy). dim0 i dim1 to rozmiar "poziomy" i "pionowy" macierzy. Część # ifdeffed-out jest naiwną implementacją. W twoim przypadku możesz zainicjować (lub przeanalizować) jednowymiarową tablicę za pomocą:

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