"Sweep" un vettore di puntatori

1

Uso un vettore per archiviare i puntatori agli oggetti. In alcuni casi distruggo uno o più di questi oggetti (impostando gli spazi vettoriali su NULL dopo ogni% chiamatadelete), che sono selezionati esternamente:

for (int i=0; i<form->SelectListBox->Items->Count; i++) {
    if (form->SelectListBox->Selected[i]) {
        delete items[i];
        items[i]=NULL;
    }
}

Dopodiché, ho cancellato tutti i puntatori NULL . Questo è quello che sto facendo e funziona:

ItemVector::iterator it;
while ((it=std::find(items.begin(), items.end(), (MyObjects*)NULL))!=items.end()) {
    items.erase(it);
}

C'è un modo più idiomatico di "spazzare" un vettore di puntatori? [1]

[1] Come avrai intuito, sto usando C ++ Builder (versione 6) e il suo VCL e provo a migrare dall'utilizzo di TList all'utilizzo di std::vector come riduci i cast statici (la classe TList fornisce un metodo Pack .

    
posta Wolf 13.05.2015 - 11:20
fonte

2 risposte

7

Il tuo algoritmo è O (N²) - se hai 1000 elementi nel tuo vettore e i primi 100 sono nulli, eseguirà il ciclo while 100 volte, ciascuno riposizionando fino a 999 elementi.

Nell'implementazione, useresti due iteratori, uno da cui leggi e uno a cui scrivi. Se l'elemento di lettura è null, non scriverlo, altrimenti riscrivilo e incrementalo.

L'algoritmo standard per farlo è chiamato remove_if e c'è una discussione dettagliata in questa domanda di stackoverflow .

    
risposta data 13.05.2015 - 12:11
fonte
0

Potresti evitare il 2 ° passaggio chiamando cancella mentre elimini l'elemento. Devi convertire l'indice in iteratore e assicurati di tenere conto del fatto che la cancellazione di elementi cambia in seguito indici

int deleted = 0;
for (int i=0; i < Count; i++) {
    if (Selected[i]) {
        delete items[i];
        items.erase(items.begin()+i-deleted++);
    }
}
    
risposta data 13.05.2015 - 16:33
fonte

Leggi altre domande sui tag