Jak usunąć element z std:: vector< > przez indeks?

Mam std::vector i chcę usunąć n ' Ten element. Jak mam to zrobić?

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

vec.erase(???);
Author: Peter Mortensen, 2009-05-17

10 answers

Aby usunąć pojedynczy element, możesz zrobić:

std::vector<int> vec;

vec.push_back(6);
vec.push_back(-17);
vec.push_back(12);

// Deletes the second element (vec[1])
vec.erase(vec.begin() + 1);

Lub, aby usunąć więcej niż jeden element na raz:

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);
 518
Author: mmmmmmmm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 18:34:41

Metoda erase na std:: vector jest przeciążona, więc prawdopodobnie lepiej jest wywołać

vec.erase(vec.begin() + index);

Gdy chcesz usunąć tylko jeden element.

 176
Author: CodeBuddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 18:28:12
template <typename T>
void remove(std::vector<T>& vec, size_t pos)
{
    std::vector<T>::iterator it = vec.begin();
    std::advance(it, pos);
    vec.erase(it);
}
 46
Author: Max,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-10 20:47:43

Metoda erase będzie stosowana na dwa sposoby:

  1. Wymazywanie pojedynczego elementu:

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. Wymazywanie zakresu elementów:

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    
 11
Author: Eswaran Pandi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-27 12:34:24

Właściwie, Funkcja erase działa dla dwóch profili:

  • Usuwanie pojedynczego elementu

    iterator erase (iterator position);
    
  • Usuwanie szeregu elementów

    iterator erase (iterator first, iterator last);
    

Od std:: vec.begin() oznacza początek kontenera i jeśli chcemy usunąć i-ten element w naszym wektorze, możemy użyć:

vec.erase(vec.begin() + index);
Jeśli przyjrzysz się uważnie, vec.begin() jest tylko wskaźnikiem do pozycji początkowej naszego wektora i dodanie do niego wartości i zwiększa wskaźnik do pozycji i, zamiast tego możemy uzyskać dostęp do wskaźnika do i-tego elementu przez:
&vec[i]

Więc możemy napisać:

vec.erase(&vec[i]); // To delete the ith element
 5
Author: Varun Garg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 18:41:56

Jeśli masz nieuporządkowany wektor, możesz skorzystać z faktu, że jest nieuporządkowany i użyć czegoś, co widziałem od Dana Higginsa na CPPCON

template< typename TContainer >
static bool EraseFromUnorderedByIndex( TContainer& inContainer, size_t inIndex )
{
    if ( inIndex < inContainer.size() )
    {
        if ( inIndex != inContainer.size() - 1 )
            inContainer[inIndex] = inContainer.back();
        inContainer.pop_back();
        return true;
    }
    return false;
}

Ponieważ kolejność listy nie ma znaczenia, po prostu weź ostatni element na liście i skopiuj go na górę elementu, który chcesz usunąć, a następnie pop i usuń ostatni element.

 5
Author: Clay J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-18 15:18:54

Jeśli pracujesz z dużymi wektorami (rozmiar > 100 000) i chcesz usunąć wiele elementów, polecam zrobić coś takiego:

int main(int argc, char** argv) {

    vector <int> vec;
    vector <int> vec2;

    for (int i = 0; i < 20000000; i++){
        vec.push_back(i);}

    for (int i = 0; i < vec.size(); i++)
    {
        if(vec.at(i) %3 != 0)
            vec2.push_back(i);
    }

    vec = vec2;
    cout << vec.size() << endl;
}

Kod pobiera każdą liczbę w vec, której nie można podzielić przez 3 i kopiuje ją do vec2. Następnie kopiuje vec2 w vec. Jest dość szybki. Aby przetworzyć 20 000 000 elementów algorytm ten zajmuje tylko 0,8 sek!

Zrobiłem to samo z metodą erase i zajmuje to dużo, dużo czasu:

Erase-Version (10k elements)  : 0.04 sec
Erase-Version (100k elements) : 0.6  sec
Erase-Version (1000k elements): 56   sec
Erase-Version (10000k elements): ...still calculating (>30 min)
 3
Author: Fabian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 18:39:17

Aby usunąć element użyj następującego sposobu:

// declaring and assigning array1 
std:vector<int> array1 {0,2,3,4};

// erasing the value in the array
array1.erase(array1.begin()+n);

Dla bardziej obszerny przegląd można odwiedzić: http://www.cplusplus.com/reference/vector/vector/erase/

 2
Author: cammando,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-06-06 20:44:56

Poprzednie odpowiedzi zakładają, że ty zawsze masz podpisany indeks. Niestety, std::vector używa size_type do indeksowania i difference_type do arytmetyki iteratora, więc nie działają razem, jeśli masz włączone "-Wconversion" i friends. Jest to kolejny sposób na odpowiedź na pytanie, będąc w stanie obsłużyć zarówno podpisane, jak i niepodpisane: {]}

Do usunięcia:

template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
void remove(std::vector<T> &v, I index)
{
    const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);
    v.erase(iter);
}

Do wzięcia:

template<class T, class I, class = typename std::enable_if<std::is_integral<I>::value>::type>
T take(std::vector<T> &v, I index)
{
    const auto &iter = v.cbegin() + gsl::narrow_cast<typename std::vector<T>::difference_type>(index);

    auto val = *iter;
    v.erase(iter);

    return val;
}
 0
Author: Rian Quinn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-06 18:43:39

Jest jeszcze jeden sposób, aby to zrobić jeśli chcesz usunąć element, znajdując go z jego wartością w wektorze, musisz to zrobić na wektorze.

vector<int> ar(n);
ar.erase(remove(ar.begin(), ar.end()), (place your value here from vector array));

Usunie twoją wartość stąd. dzięki

 0
Author: meenachinmay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-23 09:03:31