2009-11-03 4 views
3

Je veux être capable d'insérer un élément au milieu (ou un autre emplacement) dans le vecteur sans écraser l'élément existant.Quelle est l'approche la plus indolore pour insérer un élément au milieu du vecteur std :: vector

Dites que mon vecteur a 3 6 9 10 et je veux insérer 7 juste après 6. Comment devrait-il être fait sans causer de problèmes? C'est un fonctionnement très peu fréquent, donc l'efficacité n'est pas un problème ici. Aussi, à ce stade, je ne peux pas passer à un autre conteneur (par exemple: std :: list) qui est bon pour les insertions au milieu.

Est-ce que std::insert dans le vecteur fera ce que je veux? Comment?

grâce

+1

Vous ne pouvez pas insérer un élément au milieu d'un vecteur sans écraser tous les éléments après la position de dans sertion: ils seront déplacés à la fin du vecteur pour laisser de la place au nouvel élément (l'élément n sera copié à n + 1, l'élément n-1 sera copié à n, etc. supplantant ainsi les éléments existants). –

+1

Ce qui, bien sûr, signifie que tous les itérateurs existants et les pointeurs dans le vecteur seront invalidés (comme ils peuvent l'être après un vieux push_back(), d'ailleurs). – ceo

Répondre

11

Il est vector::insert pour cette opération.

iterator insert(
    iterator _Where, 
    const Type& _Val 
); 
void insert(
    iterator _Where, 
    size_type _Count, 
    const Type& _Val 
); 
1

Vous souhaitez probablement utiliser la fonction de membre d'insertion de votre vecteur.

7

J'ai édité l'exemple pour insérer '7' directement après '6' car la question est plus sur l'insertion à un endroit spécifique qu'arbitrairement au centre du vecteur.

std::vector<int> v; 
v.push_back(3); 
v.push_back(6); 
v.push_back(9); 
v.push_back(10); 
std::vector<int>::iterator insert_pos = std::find(v.begin(), v.end(), 6); 
// only increment iterator if we've found the insertion point, 
// otherwise insert at the end of the vector 
if (insert_pos != v.end()) { 
    ++insert_pos; 
} 
v.insert(insert_pos, 7); 
// v now contains 3, 6, 7, 9, 10 
+0

Peut-être ajouter une ligne où vous trouvez l'index à insérer? – Bill

+0

Ouais je me suis d'abord concentré sur la partie 'au milieu' de la question un peu trop littéralement je pense :) – irh

1

Le code d'exemple de Mash correspond au point (mais attention à ce qu'il insère là où vous vous attendez avec une taille impaire). En outre, même si vous avez dit que l'efficacité n'est pas un problème, vous pouvez envisager d'utiliser la fonction membre reserve() du vecteur pour éviter la réaffectation et la copie cachée. ("Ne pas pessimize prématurément", comme Sutter et Alexandrescu disent dans C++ normes de codage.)

2

utilisant à la fois vector::find et vector::insert, selon les commentaires ci-dessus, donne le code suivant:

std::vector<int> v; 
v.push_back(3); 
v.push_back(6); 
v.push_back(9); 
v.push_back(10); 
std::vector<int>::iterator pos = std::find(v.begin(),v.end(), 6); 
v.insert(pos, 7); 
+0

Cela ne compile pas - 'find' n'est pas un membre de' std :: vector', seulement de la conteneurs associatifs. Vous devez utiliser std :: find pour trouver le point d'insertion. – irh

+1

Désolé, réponse pré-café. Correction d'utiliser std :: find à la place. –

2

Si votre vecteur est ordonné, vous pouvez optimiser l'insertion quelque peu en évitant la recherche linéaire:

std::vector<int> v; 
v.push_back(3); 
v.push_back(6); 
v.push_back(9); 
v.push_back(10); 

std::insert(std::upper_bound(v.begin(), v.end(), 7), 7); 
+0

Peut-être que vous auriez dû dire qu'il faut "#include ", mais c'est juste ce que je veux, merci +1. – Oriol

Questions connexes