Question

J'ai un std :: vector , et je veux supprimer l'élément n'th. Comment puis-je faire?

std::vector<int> vec;

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

vec.erase(???);
Était-ce utile?

La solution

Pour supprimer un seul élément, vous pouvez faire:

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);

Ou, pour supprimer plus d'un élément à la fois:

// Deletes the second through third elements (vec[1], vec[2])
vec.erase(vec.begin() + 1, vec.begin() + 3);

Autres conseils

La méthode d'effacement sur std :: vecteur est surchargé, il est donc probablement plus clair appeler

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

quand vous voulez seulement effacer un seul élément.

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);
}

La méthode erase sera utilisée de deux façons:

  1. Effacement seul élément:

    vector.erase( vector.begin() + 3 ); // Deleting the fourth element
    
  2. plage d'effacement des éléments:

    vector.erase( vector.begin() + 3, vector.begin() + 5 ); // Deleting from fourth element to sixth element
    

Si vous avez un vecteur non ordonnée, vous pouvez profiter du fait qu'il est et non ordonnée utiliser quelque chose que j'ai vu de Dan Higgins à 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;
}

Depuis l'ordre de la liste n'a pas d'importance, il suffit de prendre le dernier élément de la liste et le copier sur le dessus de l'élément que vous voulez supprimer, puis pop et supprimer le dernier élément.

En fait, la fonction erase travaille pour deux profils:

  • Retrait d'un seul élément

    iterator erase (iterator position);
    
  • Suppression d'un ensemble d'éléments

    iterator erase (iterator first, iterator last);
    

Depuis std :: vec.begin () marque le début du récipient et si l'on veut supprimer l'élément ième dans notre vecteur, nous pouvons utiliser:

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

Si vous regardez attentivement, vec.begin () est juste un pointeur vers la position de départ de notre vecteur et en ajoutant la valeur de i à incrémente le pointeur sur la position I, donc au lieu que nous pouvons accéder au pointeur sur l'élément ième par:

&vec[i]

On peut donc écrire:

vec.erase(&vec[i]); // To delete the ith element

Si vous travaillez avec de grands vecteurs (taille> 100 000) et que vous voulez supprimer beaucoup d'éléments, je recommande de faire quelque chose comme ceci:

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;
}

Le code prend chaque numéro VEC qui ne peut pas être divisé par 3 et des copies à vec2. Ensuite, il copie vec2 en VEC. Il est assez rapide. Pour traiter 20.000.000 éléments de cet algorithme prend 0,8 sec seulement!

Je l'ai fait la même chose avec l'effacement méthode, et il faut beaucoup, beaucoup de temps:

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)

Pour supprimer un élément utiliser de la manière suivante:

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

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

Pour plus large aperçu vous pouvez visiter: http://www.cplusplus.com/reference/vector/vector/erase/

Je vous conseille de lire ce que je crois que c'est ce que vous recherchez. https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

Si vous utilisez par exemple

 vec.erase(vec.begin() + 1, vec.begin() + 3);

vous effacez n -ième élément du vecteur, mais quand vous effacez deuxième élément, tous les autres éléments du vecteur sera déplacé et vecteur de taille sera -1. Cela peut être un problème si vous boucle à travers vecteur depuis la taille du vecteur () diminue. Si vous avez un problème comme celui-ci lien fourni suggéré d'utiliser l'algorithme existant dans la bibliothèque standard C ++. et « supprimer » ou « remove_if ».

Espérons que cela a aidé

Les réponses précédentes supposent que vous toujours ont un indice signé. Malheureusement, std::vector utilise size_type pour l'indexation, et difference_type pour l'arithmétique iterator, donc ils ne travaillent pas ensemble si vous avez « -Wconversion » et les amis activés. Ceci est une autre façon de répondre à la question, tout en étant capable de gérer à la fois signé et non signé:

Pour supprimer:

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);
}

Pour prendre:

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;
}

ici est une autre façon de le faire si vous voulez supprimer un élément en trouvant cela avec sa valeur dans le vecteur, il vous suffit de le faire sur le vecteur.

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

il va supprimer votre valeur d'ici. merci

Comment cela?

void squeeze(vector<int> &v)
{
    int j = 0;
    for (int i = 1; i < v.size(); i++)
        if (v[i] != v[j] && ++j != i)
            v[j] = v[i];
    v.resize(j + 1);
}

le moyen le plus rapide (pour les concours de programmation par la complexité temporelle () = constante)

100M peut effacer un objet en 1 seconde;

    vector<int> it = (vector<int>::iterator) &vec[pos];
    vec.erase(it);

et le plus lisible: vec.erase(vec.begin() + pos);

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top