2009-03-14 11 views

risposta

21

preferisco remove_if

v.erase(remove_if(v.begin(), v.end(), 
       mem_fun_ref(&MyClass::isTiredOfLife)), 
     v.end()); 

remove_if restituisce un puntamento iteratore dopo l'ultimo elemento che è ancora nella sequenza. erase cancella tutto dal primo all'ultimo argomento (entrambi gli iteratori).

+1

I in merito dimenticato remove_if() +1 . –

+0

Molto interessante. Mai visto prima +1 – Bernard

+0

Grazie, ha funzionato. –

6

Utilizzare remove_if è il modo "giusto" per farlo. Fare attenzione a NON utilizzare un iteratore per scorrere e cancellare, poiché la rimozione di elementi invalida l'iteratore. In effetti, qualsiasi esempio che usa erase() come metodo principale è una cattiva idea sui vettori, perché cancella è O (n), che renderà il tuo algoritmo O (n^2). Questo dovrebbe essere un algoritmo O (n).

È probabile che il metodo che di seguito sia più veloce di remove_if ma, diversamente da remove_if, NON conserverà l'ordine relativo degli elementi. Se ti interessa mantenere l'ordine (cioè il tuo vettore è ordinato), usa remove_if, come nella risposta sopra. Se non si cura di ordine, e se il numero di elementi da cancellare è in genere meno di un quarto del vettore, questo metodo è probabile che sia più veloce:

for(size_t i = 0; i < vec.size();) 
    if(vec[i].isTiredOfLife()) 
    { 
     vec[i] = vec.back(); 
     vec.pop_back(); 
    } 
    else 
     ++i; 
+0

D'oh. L'ho dimenticato. È anche in grassetto nella pagina che ho linkato. : o Ho cancellato il mio post, quindi nessuno lo usa. – Bernard

+0

Non riordinerà gli elementi nel vettore? Supponendo che, per esempio, il vettore di input sia ordinato, il vettore di output no, l'ultimo elemento prenderà la posizione del primo elemento eliminato. –

+0

Potresti voler aggiornare la tua risposta per non fare più riferimento a Bernard. –