web-dev-qa-db-fra.com

Comment naviguer dans un vecteur à l'aide d'itérateurs? (C ++)

Le but est d'accéder au "nième" élément d'un vecteur de chaînes au lieu de l'opérateur [] ou de la méthode "at". D'après ce que j'ai compris, les itérateurs peuvent être utilisés pour naviguer dans les conteneurs, mais je ne les utilisais jamais auparavant, et ce que je lis est source de confusion.

Si quelqu'un pouvait me donner des informations sur la manière d'y parvenir, je l'apprécierais. Je vous remercie.

92
kevin

Vous devez utiliser les méthodes begin et end de la classe vector , qui renvoient l'itérateur faisant référence au premier et au dernier élément. .

using namespace std;  

vector<string> myvector;  // a vector of stings.


// Push some strings in the vector.
myvector.Push_back("a");
myvector.Push_back("b");
myvector.Push_back("c");
myvector.Push_back("d");


vector<string>::iterator it;  // declare an iterator to a vector of strings
int n = 3;  // nth element to be found.
int i = 0;  // counter.

// now start at from the beginning
// and keep iterating over the element till you find
// nth element...or reach the end of vector.
for(it = myvector.begin(); it != myvector.end(); it++,i++ )    {
    // found nth element..print and break.
    if(i == n) {
        cout<< *it << endl;  // prints d.
        break;
    }
}

// other easier ways of doing the same.
// using operator[]
cout<<myvector[n]<<endl;  // prints d.

// using the at method
cout << myvector.at(n) << endl;  // prints d.
96
codaddict

En règle générale, les itérateurs sont utilisés pour accéder aux éléments d'un conteneur de manière linéaire; Cependant, avec les "itérateurs à accès aléatoire", il est possible d'accéder à n'importe quel élément de la même manière que operator[].

Pour accéder à des éléments arbitraires dans un vecteur vec, vous pouvez utiliser les éléments suivants:

vec.begin()                  // 1st
vec.begin()+1                // 2nd
// ...
vec.begin()+(i-1)            // ith
// ...
vec.begin()+(vec.size()-1)   // last

Voici un exemple de modèle d'accès typique (versions antérieures de C++):

int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
    sum += *it;
}

L'avantage d'utiliser itérateur est que vous pouvez appliquer le même modèle à d'autres conteneurs :

sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
    sum += *it;
}

Pour cette raison, il est très facile de créer un code de modèle qui fonctionnera de la même manière quel que soit le type de conteneur . Un autre avantage des itérateurs est qu’ils ne supposent pas que les données résident en mémoire; Par exemple, vous pouvez créer un itérateur direct capable de lire les données d'un flux d'entrée ou de générer simplement des données à la volée (par exemple, un générateur de plage ou de nombres aléatoires).

Une autre option utilisant std::for_each et lambdas:

sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });

Depuis C++ 11, vous pouvez utiliser auto pour éviter de spécifier un nom de type très long et compliqué pour l'itérateur, comme indiqué précédemment (ou même plus complexe):

sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
    sum += *it;
}

Et, en outre, il existe une variante plus simple pour chaque variante:

sum = 0;
for (auto value : vec) {
    sum += value;
}

Et enfin, il y a aussi std::accumulate où vous devez faire attention si vous ajoutez des nombres entiers ou des nombres à virgule flottante.

54

En C++ - 11, vous pouvez faire:

std::vector<int> v = {0, 1, 2, 3, 4, 5};
for (auto i : v)
{
   // access by value, the type of i is int
   std::cout << i << ' ';
}
std::cout << '\n';

Voir ici pour les variantes: https://en.cppreference.com/w/cpp/language/range-for

41
lashgar

Les itérateurs de Vector sont des itérateurs à accès aléatoire, ce qui signifie qu'ils ressemblent et se sentent comme des pointeurs simples.

Vous pouvez accéder au nième élément en ajoutant n à l'itérateur renvoyé par la méthode begin() du conteneur, ou vous pouvez utiliser l'opérateur [].

std::vector<int> vec(10);
std::Vector<int>::iterator it = vec.begin();

int sixth = *(it + 5);
int third = *(2 + it);
int second = it[1];

Sinon, vous pouvez utiliser la fonction advance qui fonctionne avec tous les types d'itérateurs. (Vous devez vous demander si vous voulez vraiment effectuer un "accès aléatoire" avec des itérateurs non aléatoires, car cela peut être une opération coûteuse.)

std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();

std::advance(it, 5);
int sixth = *it;
15
UncleBens