Copiar vectorr 2D

Iniciado por DanFire, 16 Abril 2016, 19:06 PM

0 Miembros y 1 Visitante están viendo este tema.

DanFire

Hola!
aqui estoy con mi nueva concepcion. Tengo una pregunta bastante tonta y sé que sabia hacerlo pero estoy bloqueado en esto. A ver si me iluminais porfa ;)

Código (cpp) [Seleccionar]

typedef std::vector<std::vector<Masse*> > TabpMasses2D;
typedef std::vector<std::vector<Masse> >  TabMasses2D;

Tissu::Tissu(TabMasses2D const& m) {//elle reçoit un tableau 2D des masses (positionnées au bonne endroit
   for(size_t i(0); i<m.size(); i++) {
       for(size_t j(0); j<m[i].size(); j++) {
           mpNetMasse[i].push_back(new Masse (m[i][j]));
       }
   }//double boucle pour copier le tableau en 2D reçu en argument et creer de nouveaux pointeurs
}



Este es mi constructor que recibe un vecctor de massas y a partir de este quiero crear "punteros" (decis?)
Enfin lo suyo es copiar un vector de 2 dimensiones. Me parece que me falta un push_back() en algun sitio pero no veo dnd.

Gracias de antemano y disculpad las faltas pero este teclado es un rollo :)

ivancea96

Código (cpp) [Seleccionar]
mpNetMasse.resize(m.size());
for(size_t i(0); i<m.size(); i++) {
    mpNetMasse[i].resize(m[i].size());
    for(size_t j(0); j<m[i].size(); j++) {
        mpNetMasse[i][j] = new Masse (m[i][j]);
    }
}


Si le das un tamaño inicial, ahorras bastante (aunque quizás nos e note, vaya)

Sino, con push_back:
Código (cpp) [Seleccionar]
for(size_t i(0); i<m.size(); i++) {
    mpNetMasse.push_back(std::vector<Masse*>());
    for(size_t j(0); j<m[i].size(); j++) {
        mpNetMasse[i].push_back(new Masse (m[i][j]));
    }
}

DanFire

Vale muchas gracias!!
Lo que yo decia una tonteria de pregunta pero a veces se queda uno bloqueado...
Dices que se ahorra dandole un tamano inicial. Porque? Sigue siendo n^2 operaciones, no?

ivancea96

#3
Un vector tiene internamente un array, memoria dinámica de tamaño fijo.

Suponte que tuviera un array de 1 elemento. Cuando haces un push_back, tiene que reservar memoria para 2 elementos, luego copiar lo anterior junto al valor nuevo, y liberar la memoria antigua.

Si tiene un array de 100 elementos, y haces push_back, tendrá que copiar 100 elementos.

Si le das un tamaño fijo, te ahorras todas esas copias.


Edito: Cabe decir que esto es en la teoría. En la práctica, en vez de reservar de 1 en 1 por cada push_back(), se suele reservar más, ya sea de N en N, o de otros modos, para evitar en lo posible este problema de eficiencia.

Edito de nuevo:
Código (cpp) [Seleccionar]
#include <iostream>
#include <vector>

using namespace std;

class T{
public:
T(){cout << 'a';}  // Constructor
T(const T&){cout << 'b';}  // Constructor de copia
T(const T&&){cout << 'c';}  // Constructor de movimiento
};

int main( void ){
vector<T> v;
for(int i=0; i<10; i++){
v.push_back(T());
cout << v.capacity() << endl;
}
}


Y su salida es:
ac1
acb2
acbb4
ac4
acbbbb8
ac8
ac8
ac8
acbbbbbbbb16
ac16

DanFire

Vale muchas gracias, entiendo mejor ahora.

Stakewinner00

añadir que si se esta usando C++11 en general es mejor usar emplace_back en vez de push_back, es más eficiente (menos en algunos casos que es peor).

http://stackoverflow.com/questions/23717151/why-emplace-back-is-faster-than-push-back

HardForo

He probado el codigo de Ivan y no me corre el MinGW ......... me toca en Visual C++ o cual otro compilador ?
HardForo:  foro de Hardware y programación

Se buscan Mods y colaboradores *

ivancea96

#7
Ese código utiliza C++11 para mostrar cómo el vector usa el constructor de movimiento. Puedes quitárselo: utilizará el constructor de copia en su defecto.

Edito el código y comento los constructores.


Si no se lo quieres quitar, compila usando el estándar C++11 con -std=c++11.

HardForo

HardForo:  foro de Hardware y programación

Se buscan Mods y colaboradores *