La mejor manera de añadir vector a vector
std::vector<int> a;
std::vector<int> b;
std::vector<int> c;
Me gustaría concatenar estos tres vectores anexando b
y c
's elementos a a
. ¿Cuál es la mejor manera de hacer esto, y por qué?
1) Usando vector::insert
:
a.reserve(a.size() + b.size() + c.size());
a.insert(a.end(), b.begin(), b.end());
a.insert(a.end(), c.begin(), c.end());
b.clear();
c.clear();
2) Usando std::copy
:
a.reserve(a.size() + b.size() + c.size());
std::copy(b.begin(), b.end(), std::inserter(a, a.end()));
std::copy(c.begin(), c.end(), std::inserter(a, a.end()));
b.clear();
c.clear();
3) Usando std::move
(de C++11
):
a.reserve(a.size() + b.size() + c.size());
std::move(b.begin(), b.end(), std::inserter(a, a.end()));
std::move(c.begin(), c.end(), std::inserter(a, a.end()));
b.clear();
c.clear();
4 answers
En mi opinión, tu primera solución es la mejor manera de hacerlo.
vector<>::insert
está diseñado para añadir elemento por lo que es la solución más adecuada.
Puedes llamar a reserve
en el vector de destino para reservar un poco de espacio, pero a menos que agregues muchos vectores juntos, es probable que no proporcione muchos beneficios: vector<>::insert
sepa cuántos elementos se agregarán, evitará solo una llamada reserve
.
Nota: Si esos fueran vector
de tipo más complejo (es decir, una clase personalizada, o incluso std::string
), entonces usar std::move
podría proporcionarle un buen aumento de rendimiento, porque evitaría el constructor de copia. Para un vector de int
sin embargo, no le dará ningún beneficio.
Nota 2 : Vale la pena mencionar que usar std::move
hará que el contenido de su fuente vector
sea inutilizable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-09 13:26:31
Asumiendo que desea copiar y no mover, esta sería la mejor manera:
a.reserve(a.size()+b.size()+c.size()); // Reserve space first
a.insert(a.end(),b.begin(),b.end());
a.insert(a.end(),c.begin(),c.end());
Si quieres moverte:
a.reserve(a.size()+b.size()+c.size()); // Reserve space first
a.insert(a.end(),std::make_move_iterator(b.begin()),
std::make_move_iterator(b.end()));
a.insert(a.end(),std::make_move_iterator(c.begin()),
std::make_move_iterator(c.end()));
b.swap(std::vector<int>()); // Clear and deallocate space
c.swap(std::vector<int>()); // Clear and deallocate space
Update: Has editado tu pregunta varias veces convirtiéndola en un objetivo en movimiento. Su primera opción es ahora muy similar a mi primera sugerencia.
Actualización 2: A partir de C++11, es posible que ya no tenga que usar el truco "intercambiar con vector vacío" para borrar y desasignar espacio, dependiendo de la implementación de su biblioteca de vector
. Lo siguiente puede hacer el trabajo de una manera más intuitiva:
// Empty the vectors of objects
b.clear();
c.clear();
// Deallocate the memory allocated by the vectors
// Note: Unlike the swap trick, this is non-binding and any space reduction
// depends on the implementation of std::vector
b.shrink_to_fit();
c.shrink_to_fit();
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-21 04:00:36
La primera es la mejor opción porque insert
puede averiguar cuántos elementos está agregando y cambiar el tamaño del vector para que quepa antes de que comience a copiar. Los otros no tienen esa información, por lo que podría terminar redimensionando después de un poco de copia, lo que sería más lento que redimensionar al principio, o redimensionar más de una vez.
Sin embargo, como sugiere @michaelgoldshteyn, ya que va a hacer dos inserciones, también puede cambiar el tamaño de la matriz usted mismo con el tamaño final, lo que potencialmente ahorra una redimensionar.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-09 13:13:49
Si realmente desea agregar los datos de b
y c
en vector a
, tiene que hacer la inserción (que en realidad es su 1.):
a.reserve( a.size() + b.size() + c.size() ); // preallocate memory (see why)
a.insert( a.end(), b.begin(), b.end() );
a.insert( a.end(), c.begin(), c.end() );
Dependiendo del compilador std::copy
(su 2.) normalmente debe ser tan rápido.
Dado que un std::vector
siempre debe ser contiguo en la memoria, no puede simplemente mover (como se define en C++11) y si conoce el tamaño final debe reservar su vector (evitará reasignaciones innecesarias de su vector). Pero si realmente te preocupas por el rendimiento, deja que esto sea como tres std::vector
e itera sobre ellos cuando tengas que leer sus datos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-09 15:20:30