print geeksforgeeks for example advance c++ list iterator compare

c++ - geeksforgeeks - Compare dos elementos consecutivos en std:: list



list next c++ (5)

Me gustaría comparar dos elementos consecutivos en una lista std :: mientras recorro la lista. ¿Cuál es la forma correcta de acceder al elemento i + 1 mientras mi iterador está en el elemento i? Gracias Cobe


List es un Reversible Container, por lo que sus iteradores son Iterators bidireccionales, que es un modelo de Forward Iterator, lo cual estoy bastante seguro de que significa que puedes hacer esto (o algo equivalente, si eres alérgico a salir de la mitad de un lazo, etc.):

if (!l.empty()) { for (list<T>::const_iterator i = l.begin();;) { const T &a = *i; ++i; if (i == l.end()) break; do_comparison(a, *i); } }

No podría hacer eso con un Iterador de entrada, porque con eso los valores solo "existen" siempre y cuando tenga un iterador en ellos. Pero puedes con un iterador directo.


Boost tiene una utilidad llamada next (y su inversa, prior ) solo para ese propósito.

*itr == *next(itr)

Editar: Pero, si damos un paso atrás para mirar el bosque, la verdadera pregunta es, ¿por qué escribir a la medida tu función adjacent_find ? (Recomiendo la respuesta de Nicola Bonelli para ser aceptado.) Eso es parte de la STL, y no requiere el uso de Boost, si su código no usa Boost (gracias a los comentaristas por señalar esto).


for (list<int>::iterator it = test.begin(); it!=test.end(); it++) { cout<<*it<<":/t"; list<int>::iterator copy = it; for( list<int>::iterator it2 = ++copy; it2!=test.end();it2++){ cout<<*it2<<"/t"; } cout<<endl; }


STL proporciona el algoritmo adyacente_find () que se puede usar para encontrar dos elementos iguales consecutivos. También hay una versión con un predicado personalizado.

Estos son los prototipos:

template <class ForwardIterator> ForwardIterator adjacent_find ( ForwardIterator first, ForwardIterator last ); template <class ForwardIterator, class BinaryPredicate> ForwardIterator adjacent_find ( ForwardIterator first, ForwardIterator last, BinaryPredicate pred );


La forma más sencilla sería mantener dos iteradores (ya que de todos modos tendrá que detenerse en el penúltimo).

std::list<int>::const_iterator second = list.begin(), end = list.end(); if ( second != end ) // Treat empty list for(std::list<int>::const_iterator first = second++; // Post-increment second != end; ++first, ++second) { //... }

Tenga en cuenta que first se inicializa con el post-incremento de second por lo que cuando el ciclo se inicia first muestra list.begin() y el segundo es list.begin()+1 .

Chris Jester-Young señala que boost tiene funciones next y prior , aunque no estoy familiarizado con estas funciones (por mis pecados) su implementación es trivial (especialmente si se considera que la list tiene iteradores bidireccionales).

template <class Iterator> Iterator next(Iterator i) // Call by value, original is not changed { return ++i; } // Implementing prior is left as an exercise to the reader ;o)

Mi sensación es que el uso de next no incluye este problema, así como el mantenimiento de ambos iteradores ya que debes recordar para asegurarte de que next(i) no sea igual a end() en cada uso.

Ediciones:

  • Se solucionó el error si la lista está vacía gracias al comentario de Luc Touraille .
  • Agregar referencia a la next y por qué creo que no se ajusta a este caso de uso.