Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DanFire en 16 Abril 2016, 19:06 pm



Título: Copiar vectorr 2D
Publicado por: DanFire en 16 Abril 2016, 19:06 pm
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
  1. typedef std::vector<std::vector<Masse*> > TabpMasses2D;
  2. typedef std::vector<std::vector<Masse> >  TabMasses2D;
  3.  
  4. Tissu::Tissu(TabMasses2D const& m) {//elle reçoit un tableau 2D des masses (positionnées au bonne endroit
  5.    for(size_t i(0); i<m.size(); i++) {
  6.        for(size_t j(0); j<m[i].size(); j++) {
  7.            mpNetMasse[i].push_back(new Masse (m[i][j]));
  8.        }
  9.    }//double boucle pour copier le tableau en 2D reçu en argument et creer de nouveaux pointeurs
  10. }
  11.  
  12.  

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 :)


Título: Re: Copiar vectorr 2D
Publicado por: ivancea96 en 16 Abril 2016, 19:14 pm
Código
  1. mpNetMasse.resize(m.size());
  2. for(size_t i(0); i<m.size(); i++) {
  3.    mpNetMasse[i].resize(m[i].size());
  4.    for(size_t j(0); j<m[i].size(); j++) {
  5.        mpNetMasse[i][j] = new Masse (m[i][j]);
  6.    }
  7. }

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

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


Título: Re: Copiar vectorr 2D
Publicado por: DanFire en 16 Abril 2016, 19:20 pm
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?


Título: Re: Copiar vectorr 2D
Publicado por: ivancea96 en 16 Abril 2016, 19:27 pm
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
  1. #include <iostream>
  2. #include <vector>
  3.  
  4. using namespace std;
  5.  
  6. class T{
  7. public:
  8. T(){cout << 'a';}  // Constructor
  9. T(const T&){cout << 'b';}  // Constructor de copia
  10. T(const T&&){cout << 'c';}  // Constructor de movimiento
  11. };
  12.  
  13. int main( void ){
  14. vector<T> v;
  15. for(int i=0; i<10; i++){
  16. v.push_back(T());
  17. cout << v.capacity() << endl;
  18. }
  19. }

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


Título: Re: Copiar vectorr 2D
Publicado por: DanFire en 17 Abril 2016, 11:24 am
Vale muchas gracias, entiendo mejor ahora.


Título: Re: Copiar vectorr 2D
Publicado por: Stakewinner00 en 17 Abril 2016, 13:37 pm
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


Título: Re: Copiar vectorr 2D
Publicado por: HardForo en 17 Abril 2016, 15:07 pm
He probado el codigo de Ivan y no me corre el MinGW ......... me toca en Visual C++ o cual otro compilador ?


Título: Re: Copiar vectorr 2D
Publicado por: ivancea96 en 17 Abril 2016, 15:24 pm
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.


Título: Re: Copiar vectorr 2D
Publicado por: HardForo en 17 Abril 2016, 16:05 pm
Gracias Ivan