2010-12-14 16 views
29

Jak usunąć element ith z std::vector?Usuń element ith z C++ std :: vector

Wiem, że chcę usunąć ten element. Mam int i; and std::vector<process> pList; gdzie process jest strukturą. Chcę zrobić coś równoważne do następujących:

pList.remove(i); 

Odpowiedz

57
pList.erase(pList.begin()+i); 

Do usuwania elementu o indeksie i.

+0

Dzięki! Nie rozumiem, jak uzyskać iterator przejść do metody ... – kralco626

+2

jedna uwaga, zachowanie jest niezdefiniowane, jeśli "vector" zawiera mniej niż "i + 1" elementów. Warto na to zwrócić uwagę: –

+0

Pamiętaj, że zachowa to kolejność elementów i jest O (n). Jeśli nie potrzebujesz zachowania porządku, skorzystaj z rozwiązania O (1), o którym wspominali inni. – Joe

4

Użyj Vector.Erase. Złożoność jest liniowa w odniesieniu do liczby wymazanych elementów (destruktorów) plus liczba elementów po usunięciu ostatniego elementu (ruch).

iterator erase (iterator position); 
iterator erase (iterator first, iterator last); 
+2

Tak, widziałem to w dokumentacji, ale nadal nie mogłem wymyślić, jak z niego korzystać. – kralco626

78

Oto O (1) rozwiązanie, zakładając, że nie dbają o kolejności elementów:

#include <algorithm> 

// ... 

{ 
    using std::swap; 
    swap(pList[i], pList.back()); 
    pList.pop_back(); 
} 

Dla POD, przyporządkowanie jest szybszy niż zamiana, więc należy po prostu napisać:

pList[i] = pList.back(); 
pList.pop_back(); 

w C++ 11, można zapomnieć powyższą różnicę i zawsze używaj semantyki ruch dla maksymalnej wydajności:

if (i != pList.size() - 1) 
{ 
    // Beware of move assignment to self 
    // see http://stackoverflow.com/questions/13127455/ 
    pList[i] = std::move(pList.back()); 
} 
pList.pop_back(); 
+6

To sprytne przyjęcie zlecenia nie jest ważne. –

+1

Jeszcze szybsza wersja pomija zamianę i zamiast tego po prostu przypisuje, ponieważ ostatni element i tak otrzymuje pop_backed. – Ylisar

+0

@ Ylisar: Dla wielu typów zamiana jest znacznie wydajniejsza niż przypisanie. Przykłady obejmują większość kontenerów STL. Przypisanie jest jednak bardziej skuteczne w przypadku POD. Dzięki za przypomnienie. – fredoverflow

3
vector.erase(iterator) 

Gdzie iterator jest pozycją. Pierwszy element można uzyskać za pomocą wektora vector.begin(), a ostatni za pomocą wektora .end(). Po prostu dodaj do iteratora, aby dostać się do pożądanego elementu. np .:

pList.erase(pList.begin()+6); 

wymazać 6. pozycję.

+0

to jest 7 pozycja, czyż nie? [cplusplus.com] (http://www.cplusplus.com/reference/vector/vector/erase/) –

10

Podejście do ratowania się przed złożonością liniową!

Ponieważ vector.erase() jest złożonością liniową, sugerowałbym, aby po prostu zamienić element i z ostatnim elementem i , a następnie usunąć element na końcu (który jest faktycznie ith elementem); w ten sposób możesz uratować się od złożoności liniowej. To tylko moja myśl!

+1

"vector.erase() jest złożonością liniową" Czy istnieje książka z tablerem do takich rzeczy?Mam wrażenie, że takie szacunki wymagają gruntownej znajomości niektórych algorytmów (ale nadal mam nadzieję, że istnieje tabela ze złożonymi metodami dla każdego typu danych gdzieś). Dzięki. –

Powiązane problemy