2012-10-10 26 views
6

Debo declarar una matriz de matrices o matriz multidimensional sin saber el tamaño. que quiero hacer algo similar que hago en estos casos con arreglos simples:C++ declara una matriz de matrices sin saber el tamaño

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

tal vez pueda hacer un bucle para inicializar un puntero de punteros de esta manera:

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

Pero prefiero Don Haga esto si una mejor solución es posible.

+0

Si desea una matriz de un tamaño único conocido en tiempo de ejecución, lo que es probable que realmente quiere es un 'std :: vECTOR'. – cHao

+1

¿Has aprendido sobre la biblioteca estándar? ¿Sabes qué es un 'std :: vector'? – amdn

+0

@PuraVida Sé perfectamente la biblioteca estándar gracias. Estoy probando el rendimiento en el uso de un vector > y una matriz int [] [], así que necesito usar la matriz y, por lo tanto, es por eso que no quiero usar un bucle para inicializarla. –

Respuesta

5

¿Por qué no usar std :: vector?

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

Si no desea utilizar una matriz de punteros, se puede usar una gran variedad que se puede asignar dinámicamente después de obtener el tamaño y acceder a ella como una matriz de filas.

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

No use un 'vector' de' vectores' si el código en cuestión es sensible al rendimiento. Te enfrentarás a toneladas de errores de caché en comparación con un solo bloque grande de memoria. –

+0

@ EdS.yea esta es una de las razones y quiero intentar hacer esto sin usar un bucle para inicializarlo. –

1

Tendrá que ir con la versión en bucle. Puede hacer una ligera mejoría, que consiste en asignar un bloque grande y luego construir su propio índice int* en él:

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; 

Esto tiene la propiedad agradable que todavía se puede utilizar array[i][j] sintaxis para acceder a la matriz.

0

Si se preocupan, se puede tener un poco más comodidad por tener un ayudante

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...) }; 
    } 
}; 

Esto utiliza variadics. Utilizar de esta manera:

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

Se puede usar un único std :: vector para contener toda la matriz bidimensional y se envuelve en una clase para ocultar los detalles. Aquí hay un ejemplo, utiliza una función de miembro data(row, col) que devuelve una referencia al elemento en row y col. Incluí un ejemplo de matriz bidimensional de int donde cada entrada en la matriz se inicializa al producto de sus row y col. Cuando una instancia de esta clase está fuera del alcance, se llamará y liberará la memoria del destructor predeterminado, de esa manera no tendrá que recordar llamar a delete [] para liberar la memoria. Todos los elementos de la matriz estarán contiguos en la memoria, esto es amigable con el caché y debería proporcionarle un buen rendimiento.

#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 
} 

Cuando se ejecuta este obtendrá

8 x 7 = 56 
+0

gracias por la explicación, voy a intentar esto –

Cuestiones relacionadas