it-swarm.com.de

Wie navigiere ich mit Iteratoren durch einen Vektor? (C ++)

Das Ziel besteht darin, auf das "n-te" Element eines Zeichenfolgenvektors anstelle des Operators [] oder der "at" -Methode zuzugreifen. Soweit ich weiß, können Iteratoren verwendet werden, um durch Container zu navigieren, aber ich habe noch nie zuvor Iteratoren verwendet, und was ich lese, ist verwirrend.

Wenn mir jemand Informationen darüber geben könnte, wie dies erreicht werden kann, würde ich es begrüßen. Vielen Dank.

92
kevin

Sie müssen die begin und end Methode der vector verwenden Klasse, die den Iterator zurückgibt, der sich auf das erste bzw. das letzte Element bezieht.

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

Typischerweise werden Iteratoren verwendet, um linear auf Elemente eines Containers zuzugreifen. Mit "Iteratoren mit wahlfreiem Zugriff" ist es jedoch möglich, auf jedes Element auf dieselbe Weise zuzugreifen wie mit operator[].

Um auf beliebige Elemente in einem Vektor zuzugreifenvec, können Sie Folgendes verwenden:

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

Das Folgende ist ein Beispiel für ein typisches Zugriffsmuster (frühere Versionen von C++):

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

Der Vorteil der Verwendung von Iterator ist, dass Sie das gleiche Muster mit anderen Containern anwenden können:

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

Aus diesem Grund ist es wirklich einfach, Vorlagencode zu erstellen, der gleich funktioniert unabhängig vom Containertyp. Ein weiterer Vorteil von Iteratoren ist, dass sie nicht davon ausgehen, dass sich die Daten im Speicher befinden. Beispielsweise könnte man einen Forward-Iterator erstellen, der Daten aus einem Eingabestream lesen kann oder der einfach Daten im laufenden Betrieb generiert (z. B. einen Bereichs- oder Zufallszahlengenerator).

Eine weitere Option mit std::for_each und Lambdas:

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

Seit C++ 11 können Sie auto verwenden, um die Angabe eines sehr langen, komplizierten Typnamens des Iterators zu vermeiden (oder sogar komplexer):

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

Außerdem gibt es für jede Variante eine einfachere:

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

Und schließlich gibt es auch std::accumulate wo Sie vorsichtig sein müssen, ob Sie Ganzzahl- oder Gleitkommazahlen hinzufügen.

54

In C++ - 11 können Sie Folgendes tun:

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

Variationen finden Sie hier: https://en.cppreference.com/w/cpp/language/range-for

41
lashgar

Die Iteratoren von Vector sind Iteratoren mit wahlfreiem Zugriff, was bedeutet, dass sie wie einfache Zeiger aussehen und sich anfühlen.

Sie können auf das n-te Element zugreifen, indem Sie dem von der begin() -Methode des Containers zurückgegebenen Iterator n hinzufügen, oder Sie können den Operator [] Verwenden.

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

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

Alternativ können Sie die Funktion advance verwenden, die mit allen Arten von Iteratoren funktioniert. (Sie müssten überlegen, ob Sie wirklich "Direktzugriff" mit Iteratoren ohne Direktzugriff durchführen möchten, da dies eine teure Sache sein könnte.)

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

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