¿Esto se puede hacer mejor? (C++ iteradores)

Iniciado por Orubatosu, 1 Diciembre 2014, 11:06 AM

0 Miembros y 1 Visitante están viendo este tema.

Orubatosu

Estoy trasteando con iteradores para conseguir aprender como funcionan, o mejor dicho: estoy intentando "soltarme" con su manejo y coger soltura.

Entre otras cosillas, he montado una función que devuelve un iterador indicando el valor mas alto de un vector, y funciona eso está claro, pero no se porque lo veo "feo" y pienso que tiene que haber algún modo mas elegante de hacerlo.

A ver si me podéis decir si esto se puede hacer de algún modo mas simple


#include <iostream>
#include <vector>
using namespace std;

vector<double>::iterator maximo(vector<double>& v){
    vector<double>::iterator it = v.begin();
    vector<double>::iterator ret = it;
    if (v.empty()){
        it= v.end();
        return it;
    }
    double max=*it;
    for (it++; it!=v.end(); it++){
        if (*it > max){
        max=*it;
        ret = it;
       }
    }
    return ret;
    }

int main(){
    vector<double> Datos = {1.1, 2.2, 300.3, 5.5, 98.5, -12.5};
    vector<double>::iterator itd;
    itd = maximo (Datos);
    cout << *itd;
}


"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

eferion

#1
Algo así:

Código (cpp) [Seleccionar]
vector<double>::iterator maximo(vector<double>& v)
{
 vector<double>::iterator it;
 vector<double>::iterator to_return = v.begin( );

 double max = numeric_limits<double>::min( );

 for ( it = v.begin( ) ; it != v.end( ); ++it )
 {
   if ( *it > max )
   {
     to_return = it;
     max = *it;
   }
 }

 return to_return;
}


O, usando C++11

Código (cpp) [Seleccionar]
vector<double>::iterator maximo(vector<double>& v)
{
 auto to_return = v.begin( );

 double max = numeric_limits<double>::min( );

 for ( it = v.begin( ) ; it != v.end( ); ++it )
 {
   if ( *it > max )
   {
     to_return = it;
     max = *it;
   }
 }

 return to_return;
}





V2.0:

Código (cpp) [Seleccionar]
vector<double>::iterator maximo(vector<double>& v)
{
   return std::max_element( v.begin( ), v.end( ) );
}


Vale que con esta última versión no vas a practicar demasiado con los iteradores... pero nunca hay que perder de vista que la stl tiene infinidad de herramientas que hacen que no tengamos que reinventar la rueda cada dos por tres.

Un saludo.

Orubatosu

Aha... voy a estudiarme esto a ver que ideas saco.

Si bueno, se que la stl tiene dentro de la librería <algorithm> autenticas filigranas, pero como funcionan en su mayoría a golpe de iteradores antes de meterme ahi quiero tener el tema de los iteradores "mascado" a consciencia. De nada me sirve ponerme a correr si antes no ando correctamente, ya me entiendes.
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

eferion

Lo cierto es que, pensando un poco más, no hace falta usar "max":

Código (cpp) [Seleccionar]
vector<double>::iterator maximo(vector<double>& v)
{
  auto it = v.begin( );
  auto to_return = it;

  for ( ++it ; it != v.end( ); ++it )
  {
    if ( *it > *to_return )
      to_return = it;
  }

  return to_return;
}

Orubatosu

"Auto" es un tipo nuevo de C++11 ¿no?

Tengo entendido que asume el "tipo correcto" para la expresión con la que se pretende inicializar la variable.

¿Podrías decirme donde está en http://www.cplusplus.com/ la referencia a este tipo?

Aprender a usarlo me ahorraría montones de dolores de cabeza, por no hablar de claridad de código. Cuando empiezas a liarla con iteradores constantes ya la longitud de algunas líneas se dispara con una facilidad pasmosa

Por ejemplo, dejar algo como


vector<Usuario>::const_iterator it = v.begin();


así


auto it = v.begin();


Ya sería la monda, porque dejarte sin querer cualquier pijadita por en medio a veces da unos dolores de cabeza tremendos
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998

eferion

Desde mi punto de vista, "auto" no debe usarse indiscriminadamente, solo en aquellos casos en los que el código quede más claro (por ejemplo en el caso de iteradores... todos conocemos los iteradores y no hace falta decir... esto es un iterador). Sin embargo, si de un vistazo rápido no consigues adivinar el tipo al que va a equivaler "auto" entonces es mejor usar el nombrado tradicional. Eso sí, es mi punto de vista, no intento que nadie piense igual.

Por otro lado, no se si cplusplus tiene documentación dedicada de forma exclusiva a la palabra "auto", no obstante, si buscas en google puedes encontrar bastante documentación:

http://en.cppreference.com/w/cpp/language/auto

Un saludo.

Orubatosu

Esa es precisamente la idea, ya que cuando empiezas a jugar con vectores normales, constantes, iteradores, tuplas, vectores de tuplas, interadores constantes o no de vectores de tuplas... es bastante fácil dejarte algo por el camino, pero de momento voy a seguir con el método "tradicional"

El porque es simplemente porque "la letra con sangre entra"... cuando tenga el tema dominado desde luego tiraré por el auto, pero no hasta entonces.

Gracias por todo  ;-)
"When People called me freak, i close my eyes and laughed, because they are blinded to happiness"
Hideto Matsumoto 1964-1998