Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: fafafa01 en 27 Septiembre 2017, 01:33 am



Título: crear matriz con new en una clase c++
Publicado por: fafafa01 en 27 Septiembre 2017, 01:33 am
Buenas ¿puedo hacer esto en c++?

Código
  1. class A
  2. {
  3. private:
  4.          int N;
  5.          int(*p)[N];
  6. public:
  7.          A(int N);
  8.          ~A();
  9. }
  10.  
  11. A::A(int N)
  12. {
  13.          this->N;
  14.          p=new int [N][N];
  15. }
  16. A::~A(){}
  17.  

En caso de que no, ¿como podria hacer una matriz con new que reserve de una vez las NxN celdas y asi me queden todas las celdas juntas (con respecto a la dirección de memoria)?


Título: Re: crear matriz con new en una clase c++
Publicado por: ivancea96 en 28 Septiembre 2017, 22:09 pm
Salvo que quieras hacer algún "hack" , 1 new y un for para hacer otros new es la solución normal.

Otra opción es reservar NxM elementos, y acceder con la fórmula (siendo 'i' el primer índice y 'j' el segundo): matriz[j + i*N]. Teniendo cuidado con matrices especialmente grandes ya que es más probable que obtengas un error al tratar de encontrar NxMx(sizeof) bytes contiguos (cosa más complicada si lo divides en filas).

En cuanto a eficiencia, si bien compiten bastante (y no olvidando que utilizar varios punteros aumenta mucho la legibilidad), se pueden ver pequeños cambios:

Código
  1. #include <ctime>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. template <typename ...Args>
  7. void test(void(*func)(Args...), const char* text, Args... args){
  8.    clock_t cl = clock();
  9.  
  10.    func(args...);
  11.  
  12.    cout << (clock() - cl) << "ms on: " << text << endl;
  13. }
  14.  
  15. int main(){
  16.    const int N = 1000, M = 1000, TIMES = 1000;
  17.  
  18.    int **mat1;
  19.    int *mat2;
  20.  
  21.    test(+[](int*** mat){
  22.        *mat = new int*[N];
  23.        for(int i = 0; i < N; i++){
  24.            (*mat)[i] = new int[M];
  25.        }
  26.    }, "Initialization 1", &mat1);
  27.  
  28.    test(+[](int** mat){
  29.        *mat = new int[N*M];
  30.    }, "Initialization 2", &mat2);
  31.  
  32.  
  33.    test(+[](int** mat){
  34.        for(int l = 0; l < TIMES; l++){
  35.            for(int i = 0; i < N; i++){
  36.                for(int j = 0; j < M; j++){
  37.                    volatile int k = mat[i][j];
  38.                }
  39.            }
  40.        }
  41.    }, "Loop 1 - 1", mat1);
  42.  
  43.        test(+[](int** mat){
  44.            for(int l = 0; l < TIMES; l++){
  45.                for(int i = 0; i < N; i++){
  46.                    for(int j = 0; j < M; j++){
  47.                        volatile int k = mat[j][i];
  48.                    }
  49.                }
  50.            }
  51.        }, "Loop 1 - 2", mat1);
  52.  
  53.    test(+[](int* mat){
  54.        for(int l = 0; l < TIMES; l++){
  55.            for(int i = 0; i < N; i++){
  56.                for(int j = 0; j < M; j++){
  57.                    volatile int k = mat[j + i*N];
  58.                }
  59.            }
  60.        }
  61.    }, "Loop 2", mat2);
  62. }

Citar
2ms on: Initialization 1
0ms on: Initialization 2
2514ms on: Loop 1 - 1
3296ms on: Loop 1 - 2
2001ms on: Loop 2


Título: Re: crear matriz con new en una clase c++
Publicado por: _TTFH_3500 en 28 Septiembre 2017, 23:41 pm

Una forma es almacenar los NxN elementos en un arreglo, el elemento de la posicion A(i,j) se almacena en A(i*N+j) y reciprocamente el elemento el la posicion i se encuentra en la fila i div N,
 y en la columna j (mod N)

Código
  1. int* matriz = new int[N * N];
  2. for (int i = 0; i < N * N; i++) {
  3. int fila = i / N;
  4. int columna = i % N;
  5. matriz[fila * N + columna] = valor; // matriz[i] = valor
  6. }

Y la forma tipica usando memoria dinámica:
Código
  1. int** matriz = new int*[N];
  2. for (int i = 0; i < N; i++)
  3. matriz[i] = new int[N];
  4. for (int i = 0; i < N; i++)
  5. for (int j = 0; j < N; j++)
  6. matriz[i][j] = valor;