cplusplus - ¿Cómo navegar a través de un vector usando iteradores?(C++)
list iterator c++ (3)
Los iteradores de vectores son iteradores de acceso aleatorio, lo que significa que se ven y se sienten como indicadores simples.
Puede acceder al enésimo elemento agregando n al iterador devuelto por el método begin()
del contenedor, o puede usar operator []
.
std::vector<int> vec(10);
std::Vector<int>::iterator it = vec.begin();
int sixth = *(it + 5);
int third = *(2 + it);
int second = it[1];
Alternativamente, puede usar la función de advance que funciona con todo tipo de iteradores. (Debería considerar si realmente desea realizar un "acceso aleatorio" con iteradores de acceso no aleatorio, ya que podría ser una tarea costosa).
std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();
std::advance(it, 5);
int sixth = *it;
El objetivo es acceder al elemento "enésimo" de un vector de cadenas en lugar del operador [] o el método "at". Por lo que entiendo, los iteradores pueden usarse para navegar a través de contenedores, pero nunca he usado iteradores antes, y lo que estoy leyendo es confuso.
Si alguien pudiera darme alguna información sobre cómo lograr esto, lo agradecería. Gracias.
Normalmente, los iteradores se utilizan para acceder a elementos de un contenedor de forma lineal; sin embargo, con "iteradores de acceso aleatorio", es posible acceder a cualquier elemento de la misma manera que operator[]
.
Para acceder a elementos arbitrarios en un vector vec
, puede usar lo siguiente:
vec.begin() // 1st
vec.begin()+1 // 2nd
// ...
vec.begin()+(i-1) // ith
// ...
vec.begin()+(vec.size()-1) // last
El siguiente es un ejemplo de un patrón de acceso típico (versiones anteriores de C ++):
int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
La ventaja de utilizar iterator es que puede aplicar el mismo patrón con otros contenedores :
sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
sum += *it;
}
Por este motivo, es muy fácil crear un código de plantilla que funcione de la misma forma independientemente del tipo de contenedor . Otra ventaja de los iteradores es que no supone que los datos residen en la memoria; por ejemplo, se podría crear un iterador directo que pueda leer datos de un flujo de entrada, o que simplemente genere datos sobre la marcha (por ejemplo, un generador de rango o de números aleatorios).
Otra opción para usar std::for_each
y lambdas:
sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
Desde C ++ 11 puede usar auto
para evitar especificar un nombre de tipo muy largo y complicado del iterador como se vio antes (o incluso más complejo):
sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
Y, además, hay una variante para cada uno más simple:
sum = 0;
for (auto value : vec) {
sum += value;
}
Y finalmente también hay std::accumulate
donde tienes que tener cuidado ya sea que estés agregando números enteros o de coma flotante.
Necesita hacer uso del método begin
y end
de la clase vector
, que devuelve el iterador refiriéndose al primer y último elemento, respectivamente.
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.