2010-10-11 18 views
13

Soy nuevo en C/C++ y he estado persiguiendo mi cabeza, pero todavía tengo ni idea de cómo hacer una "estructura" como estomatriz 3D C++ utilizando int [] operador

alt text

Se supone que es una matriz dinámica 3D usando punteros.

empecé como este, pero quedó atascado allí

int x=5,y=4,z=3; 
    int ***sec=new int **[x]; 

Sería suficiente para saber cómo hacer que sea de un tamaño estática de Y y Z;

Por favor, le agradecería que me ayudes.

Gracias de antemano.

Respuesta

19

Para crear dinámicamente matriz 3D de números enteros, es mejor entender 1D y 2D primera matriz.

serie 1D: Usted puede hacer esto muy fácilmente por

const int MAX_SIZE=128; 
int *arr1D = new int[MAX_SIZE]; 

Aquí, estamos creando un int-puntero que apunte a un trozo de memoria donde se pueden almacenar números enteros.

matriz 2D: Puede usar la solución de la matriz 1D anterior para crear una matriz 2D. Primero, cree un puntero que debe apuntar a un bloque de memoria donde solo se mantienen otros punteros enteros que finalmente apuntan a datos reales. Dado que nuestro primer puntero apunta a una matriz de punteros, esto se llamará puntero-a-puntero (puntero doble).

const int HEIGHT=20; 
const int WIDTH=20; 

int **arr2D = new int*[WIDTH]; //create an array of int pointers (int*), that will point to 
           //data as described in 1D array. 
for(int i = 0;i < WIDTH; i++){ 
     arr2D[i] = new int[HEIGHT]; 
} 

3D matriz: Esto es lo que quiere hacer. Aquí puede probar el esquema utilizado en los dos casos anteriores. Aplica la misma lógica que la matriz 2D. El diagrama en cuestión lo explica todo. La primera matriz será puntero-a-puntero-a-puntero (int *** - ya que apunta a punteros dobles). La solución es la siguiente:

const int X=20; 
const int Y=20; 
const int z=20; 

int ***arr3D = new int**[X]; 
for(int i =0; i<X; i++){ 
    arr3D[i] = new int*[Y]; 
    for(int j =0; j<Y; j++){ 
     arr3D[i][j] = new int[Z]; 
     for(int k = 0; k<Z;k++){ 
      arr3D[i][j][k] = 0; 
     } 
    } 
} 
+0

También se puede utilizar este método para las matrices N-Dimensión con N-1 para los bucles. –

+7

tal vez mencionan la funcionalidad de eliminación correspondiente, así .. – stijn

+0

@Manish Shukla En el código de matriz de 3D, que de X, Y, y Z representa anchura, altura y profundidad ?? – Mariya

0

OK tomemos sus inicios

int ***sec = new int**[x]; 

seg es ahora una matriz de int s ** de longitud x, por lo que ahora sólo voy a centrarse en hacer que el elemento zeroeth ser lo que quieres

sec[0] = new int*[y]; 

ahora seg [0] apunta a matriz de int s * de longitud Y, ahora sólo tiene que conseguir el último bit del árbol de hecho, por lo

sec[0][0] = new int[z]; 

Y finalmente para conseguir que se forma en su diagrama

sec[0][0][z-1] = 0; 

Esto parece un poco como una pregunta tarea, asegúrese de que realmente entiende la respuesta y por qué funciona.

+0

'sec' no es una matriz. Es un puntero que apunta al primer elemento de una matriz. – sellibitze

+0

Eso es más bien semántico. Para ser justos en casos como int x [10]; x es realmente un puntero al primer elemento de una matriz, y una matriz a la vez. Realmente no hay diferencia entre ser un puntero al primer elemento de una matriz y ser una matriz. –

1

Usted puede tratar de:

for(int i=0;i<x;i++) { 
    sec[i] = new int *[y]; 
    for(int j=0;j<y;j++) { 
    sec[i][j] = new int [z]; 
    } 
} 

Y una vez que haya terminado de usar esta memoria se desasignar como:

for(int i=0;i<x;i++) { 
    for(int j=0;j<y;j++) { 
    delete [] sec[i][j]; 
    } 
    delete [] sec[i]; 
} 
delete [] sec; 
11
// one-liner 
typedef std::vector<std::vector<std::vector<int> > > ThreeDimensions; 
// expanded 
typedef std::vector<int> OneDimension; 
typedef std::vector<OneDimension> TwoDimensions; 
typedef std::vector<TwoDimension> ThreeDimensions; 

(esto se etiqueta C++, después de todo)

EDITAR en respuesta a la pregunta de Joe

hola de nuevo Joe =) Seguro. he aquí el ejemplo:

#include <vector> 
#include <iostream> 

int main(int argc, char* const argv[]) { 

    /* one-liner */ 
    typedef std::vector<std::vector<std::vector<int> > >ThreeDimensions; 
    /* expanded */ 
    typedef std::vector<int>OneDimension; 
    typedef std::vector<OneDimension>TwoDimensions; 
    typedef std::vector<TwoDimensions>ThreeDimensions; 

    /* 
     create 3 * 10 * 25 array filled with '12' 
    */ 
    const size_t NElements1(25); 
    const size_t NElements2(10); 
    const size_t NElements3(3); 
    const int InitialValueForAllEntries(12); 

    ThreeDimensions three_dim(NElements3, TwoDimensions(NElements2, OneDimension(NElements1, InitialValueForAllEntries))); 

    /* the easiest way to assign a value is to use the subscript operator */ 
    three_dim[0][0][0] = 11; 
    /* now read the value: */ 
    std::cout << "It should be 11: " << three_dim[0][0][0] << "\n"; 
    /* every other value should be 12: */ 
    std::cout << "It should be 12: " << three_dim[0][1][0] << "\n"; 

    /* get a reference to a 2d vector: */ 
    TwoDimensions& two_dim(three_dim[1]); 

    /* assignment */ 
    two_dim[2][4] = -1; 
    /* read it: */ 
    std::cout << "It should be -1: " << two_dim[2][4] << "\n"; 

    /* get a reference to a 1d vector: */ 
    OneDimension& one_dim(two_dim[2]); 

    /* read it (this is two_dim[2][4], aka three_dim[1][2][4]): */ 
    std::cout << "It should be -1: " << one_dim[4] << "\n"; 
    /* you can also use at(size_t): */ 
    std::cout << "It should be 12: " << one_dim.at(5) << "\n"; 

    return 0; 
} 
+0

1 para el camino a seguir * * si esta distribución de la memoria es realmente lo que el PO quiere – sellibitze

1

Respuestas integrales.

Si realmente está escribiendo esto en C++ (no en bruto C), creo que debería echar otro vistazo a esta complicada estructura de datos. rediseñar la OMI sin perder de vista lo que está tratando de hacer sería mejor.

1

Lo que estás tratando de hacer no es idiomático en C++. Por supuesto, usted puede utilizar un int***pointer para esto, pero esto no es recomendable. En C++ tenemos mejores formas de llegar allí.

vector<vector<vector<int> > > foo (5,vector<vector<int> >(4, vector<int>(3))); 

Esto dará como resultado algo con el diseño de memoria similar a lo que usted solicitó. Es compatible con el cambio de tamaño dinámico y vectores internos para tener diferentes tamaños al igual que en su imagen. Además, no tiene que preocuparse por la asignación/eliminación manual de nada de eso. Además, los vectores conocen su tamaño para que no tenga que recordarlo en alguna parte.

Pero si solo quiere una matriz 3D "rectangular" donde todos los elementos están almacenados consecutivamente en el mismo bloque de memoria, podría usar un boost::multiarray.