2013-07-14 11 views
15

voglio duplicare il contenuto del vettore e voglio loro di essere aggiunti alla fine del vettore originale cioè v[i]=v[i+n] for i=0,2,...,n-1Bel modo per aggiungere un vettore a sé

Sto cercando un bel modo per farlo, non con un ciclo. Ho visto std::vector::insert ma la versione iterativa vieta un iteratore a *this (il comportamento di i.e non è definito).

ho anche provato std::copy come segue (ma si è tradotto in errore di segmentazione):

copy(xx.begin(), xx.end(), xx.end());

+0

possibile duplicato del [risultati errati quando si aggiunge vettore a se stessa utilizzando la copia e indietro \ _inserter] (http://stackoverflow.com/questions/11511510/wrong-results-when-appending-vector-to-itself-using-copy-and-back-inserter) –

+1

@BenVoigt, per essere onesti, quando ho fatto quella domanda, l'ho provato e voluto per sapere perché non ha funzionato. In realtà non avevo bisogno di una soluzione di lavoro elegante, quindi nei commenti ci sono solo menzioni. – chris

+1

Devo chiedermi se la maggior parte delle persone avrebbe avuto l'implementazione giusta la prima volta se l'hanno codificata con un ciclo. – MarkB

risposta

21

Wow. Così tante risposte che sono vicine, nessuna con tutti i pezzi giusti. Sono necessari sia resize (o reserve) sia copy_n, insieme a ricordare la dimensione originale.

auto old_count = xx.size(); 
xx.resize(2 * old_count); 
std::copy_n(xx.begin(), old_count, xx.begin() + old_count); 

o

auto old_count = xx.size(); 
xx.reserve(2 * old_count); 
std::copy_n(xx.begin(), old_count, std::back_inserter(xx)); 

Quando si utilizza reserve, copy_n è necessaria perché il end() punti iteratore un elemento oltre il fine ... il che significa che non è anche "prima del punto di inserimento" della prima inserimento, e diventa non valido.


23.3.6.5 [vector.modifiers] promesse che per insert e push_back:

Note: Provoca riallocazione se la nuova dimensione è superiore alla vecchia capienza. Se non si verifica alcuna riallocazione, tutti gli iteratori e i riferimenti prima del punto di inserimento rimangono validi. Se viene generata un'eccezione diversa dal costruttore di copie, dal costruttore di movimento, dall'operatore di assegnazione o dall'operatore di spostamento di T o da qualsiasi operazione di InputIterator, non vi sono effetti. Se un'eccezione viene generata dal costruttore di mosse di una T non inseribile in copia, gli e ff etti non sono specificati.

3

lo farei in questo modo:

#include <algorithm> 
#include <vector> 
#include <utility> 

int main(int argc, char* argv[]) 
{ 
    std::vector<int> v1 = { 1, 2, 3, 4, 5 }; 

    { 
     std::vector<int> v2(v1.begin(), v1.end()); 
     std::copy(v1.begin(), v1.end(), std::back_inserter(v2)); 
     std::swap(v1, v2); 
    } 

    return 0; 
} 

EDIT: ho aggiunto una versione leggermente più efficiente.

#include <algorithm> 
#include <vector> 
#include <utility> 

int main(int argc, char* argv[]) 
{ 
    std::vector<int> v1 = { 1, 2, 3, 4, 5 }; 

    { 
     typedef std::move_iterator<decltype(v1)::iterator> VecMoveIter; 
     std::vector<int> v2(v1); 
     std::copy(VecMoveIter(v1.begin()), VecMoveIter(v1.end()), std::back_inserter(v2)); 
     v1 = std::move(v2); 
    } 

    return 0; 
} 
+0

Hai dimenticato l'esistenza di un costruttore di copia e 'std :: vector :: insert' :) – chris

+0

Non è un cattivo pensiero, perché il contenuto vettoriale probabilmente verrà comunque copiato in una nuova posizione. Ma stai aggiungendo una copia extra. Prova a costruire il nuovo vettore con la giusta capacità in attacco. –

+0

Inoltre, sarebbe opportuno copiare una volta e spostare gli elementi esistenti invece di crearne due nuove. –

0

Per aggiungere più di uno slot di duplicati.

int main() { 
     std::vector<int> V; 
     V.push_back(1); 
     V.push_back(2); 

     int oldSize = V.size(); 
     int newSize = oldSize; 
     int nDupSlot = 4; 

     V.resize(nDupSlot * oldSize); 
     for(int i=0; i<(nDupSlot-1); ++i) { 
      std::copy_n(V.begin(), oldSize, V.begin() + newSize);  
      newSize = newSize + oldSize; 
     } 

     for(int i =0; i<V.size(); ++i) { 
      std::cout<<V[i]; 
      } 

     return 0; 
    } 

uscita:

12121212 
0

Potrebbe non essere il modo più efficace, ma di sicuro è semplice:

std::vector<int> toAppend(xx); 
xx.insert(xx.end(), toAppend.begin(), toAppend.end(); 
Problemi correlati