2012-10-10 30 views
6

Devo dichiarare una matrice di matrici o array multidimensionale senza conoscere la dimensione. Voglio fare qualcosa di simile che faccio in questi casi con semplice array:C++ dichiara una matrice di matrici senza conoscere la dimensione

int *array; 
cin >> size; 
array = new int[size]; 

Forse posso fare un ciclo per inizializzare un puntatore di puntatori in questo modo:

int **array; 
cin >> rows >> col; 
array = new *int[rows] 
for (int i = 0; i < rows; ++i) 
    array[i] = new int[col]; 

Ma io preferisco don Lo faccia se è possibile una soluzione migliore.

+0

Se si desidera un array di dimensioni conosciuto solo in fase di esecuzione, quello che probabilmente vuole veramente è un 'std :: VECTOR'. – cHao

+1

Hai imparato a conoscere la libreria standard? Sai cos'è un 'std :: vector'? – amdn

+0

@PuraVida Conosco perfettamente la libreria standard grazie. Sto testando le prestazioni sull'uso di un vettore > e un array int [] [], quindi ho bisogno di usare l'array e quindi è il motivo per cui non voglio usare un ciclo per inizializzarlo. –

risposta

5

Perché non utilizzare std :: vector?

std::vector<std::vector<int> > array; 

Se non si desidera utilizzare un array di puntatori, è possibile utilizzare una vasta gamma di allocare dinamicamente dopo si ottiene la dimensione e accedervi come una matrice di righe.

int rows = 10; 
int columns = 20; 

int* array = new int[rows * columns]; 

for (int count = 0; count < rows; count++) 
{ 
    int* row = &array[count * columns]; 

    for (int inner_count = 0; inner_count < columns; inner_count++) 
    { 
     int* element = &row[inner_count]; 

     //do something 
    } 
} 

delete [] array; 
+2

Non utilizzare un 'vector' di' vettori' se il codice in questione è sensibile alle prestazioni. Affronterai tonnellate di errori di cache rispetto ad un unico grande blocco di memoria. –

+0

@ EdS.yea questo è uno dei motivi e voglio provare a farlo senza utilizzare un ciclo per inizializzarlo. –

1

Stai per andare con la versione loop. È possibile effettuare un lieve miglioramento, che è quello di allocare un unico grande blocco e quindi costruire il proprio indice di int* in esso:

int **array; 
int *storage; 
cin >> rows >> col; 
array = new *int[rows]; 
storage = new int[rows*col]; 
for (int i = 0; i < rows; ++i) 
    array[i] = storage + col * i; 

Questa ha la proprietà bello che si può ancora utilizzare array[i][j] sintassi per l'accesso alla matrice.

0

Se si cura, si può avere un po 'più convenienza da avere un aiutante

template <typename T> 
struct C3DArray 
{ 
    vector<vector<vector<T>>> m; 
    C3DArray(int size_x, int size_y, int size_z) 
     : m(make(T(), size_z, size_y, size_x)) 
    { } 

    template <typename U> static std::vector<U> make(U v, size_t n) { 
     return { n, std::move(v) }; 
    } 

    template <typename U, typename... Dim> static auto make(U v, size_t n, Dim... other) 
     -> std::vector<decltype(make(v, other...))> { 
     return { n, make(v, other...) }; 
    } 
}; 

Questo utilizza variadics. Utilizzare in questo modo:

C3DArray<int> arr(3,4,20); 
0

è possibile utilizzare un singolo std :: vector per contenere l'intera matrice bidimensionale e avvolgerlo in una classe per nascondere i dettagli. Ecco un esempio, utilizza una funzione membro data(row, col) che restituisce un riferimento all'elemento su row e col. Ho incluso una matrice di esempio 2 dimensionale di int in cui ogni voce nell'array è inizializzata sul prodotto del suo row e col. Quando un'istanza di questa classe esce dall'ambito, il distruttore predefinito viene chiamato e rilascia la memoria, in questo modo non è necessario ricordare di chiamare delete [] per rilasciare la memoria. Tutti gli elementi della matrice saranno contigui nella memoria, questo è cache friendly e dovrebbe darti buone prestazioni.

#include <iostream> 
#include <vector> 
#include <stdexcept> 

template <typename T> 
class matrix { 
    std::vector<T> data_; 
public: 
    size_t const rows_; 
    size_t const cols_; 
    matrix(size_t rows, size_t cols) 
     : rows_(rows) 
     , cols_(cols) 
     , data_(rows * cols) 
    {} 
    T& data(size_t row, size_t col) { 
     if (row > rows_ || col > cols_) throw std::out_of_range("matrix"); 
     return data_[ row * cols_ + col ]; 
    } 
}; 

int main(int argc, char** argv) 
{ 
    matrix<int> array(100,100); 

    for(size_t r=0; r < array.rows_; ++r) { 
     for(size_t c=0; c < array.cols_; ++c) { 
      array.data(r,c) = r * c; 
     } 
    } 

    std::cout << "8 x 7 = " << array.data(8,7) << std::endl; 

    return 0; // array goes out of scope here, memory released automatically 
} 

Quando si esegue questo si otterrà

8 x 7 = 56 
+0

grazie per la spiegazione, ci proverò –

Problemi correlati