Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Necesito orientacion con el siguiente codigo

Estas en el tema de Necesito orientacion con el siguiente codigo en el foro de C/C++ en Foros del Web. Hola amigos, hoy estando con la niña ayudándote con los deberes le venía esta tarea: Cómo ella tiene 9 años y es un trabajo para ...
  #1 (permalink)  
Antiguo 12/01/2016, 10:53
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Necesito orientacion con el siguiente codigo

Hola amigos, hoy estando con la niña ayudándote con los deberes le venía esta tarea:

Cómo ella tiene 9 años y es un trabajo para el cole pues tiene que hacerlo con el lápiz y a mano pero a mI me surgió la duda de si quisiera crear un código que me muestre todos los caminos. Decir que se puede ir hacia las cuatro direcciones sin repetir ninguna celda ¿como habría que plantearlo? Se me ocurrió usar una serie de bucles anidados que realice todas las combinaciones posibles pero no veo el modo. Me gusta este tipo de retos porque soy muy curioso y suelo aprender cosas interesantes con ellos. ¿alguien puede orientarme?
  #2 (permalink)  
Antiguo 12/01/2016, 11:03
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Necesito orientacion con el siguiente codigo

Podrías usar Djisktra para resolverlo. Dentro de los algoritmos de encaminamiento es, en mi opinión, uno de los más sencillos de implementar.

Lo que tienes frente a tí no es más que un grafo con pesos en sus nodos. Lo que tienes que hacer es buscar el camino con peso mínimo.

Este es un clásico dentro de los algoritmos usados por los GPS para llevarte a tu destino. El peso de los nodos puede ser la distancia, la velocidad de la vía, el tiempo empleado (depende de la distancia y de la velocidad máxima de la vía), el camino con menos desnivel, ... al final todo consiste en asignar pesos a los nodos y dejar que un algoritmo de encaminamiento haga su trabajo :).

EDITO: Aunque los algoritmos de encaminamiento van encaminados a encontrar la ruta más corta con un par de cambios puedes hacer que tu algoritmo busque rutas con un peso específico... simplemente hay que ir descartando las rutas que vayas encontrando con pesos menores al deseado y quedarte con la primera (o con todas) las que cumplan el peso deseado.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #3 (permalink)  
Antiguo 12/01/2016, 14:31
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

La verdad es que escapa a mis conocimientos actuales ya que ni siquiera se aun que es un grafo y ya lo de con peso ni te cuento jejeje.
Pensé que iba a ser algo sencillo pero tengo mucho aun que aprender para esto.
Lo dejare aparcado y algún día en el futuro lo retomaré.
  #4 (permalink)  
Antiguo 13/01/2016, 03:30
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Necesito orientacion con el siguiente codigo

Un grafo es lo que tienes en la imagen que has puesto en el mensaje: Una serie de nodos unidos entre ellos. Vale, puede ser una descripción un poco vaga pero para lo que necesitas sirve.

Los pesos los puedes interpretar como el coste de llegar de un nodo A a otro B mediante la unión que los une. El peso no tiene unidades y es, por tanto, algo abstracto. Puede significar lo que tu quieras: distancia (mayor peso mayor distancia. p.ej: 1peso=1metro), tiempo para cruzar la unión (mayor peso mayor tiempo. p.ej: 1peso=1minuto), ...

Todo lo anterior, repito, cubre únicamente una parte de la temática de los grafos, pero con eso ya se podría empezar a trabajar en el ejercicio.

En el caso del ejercicio de tu hija, para que tenga algo de sentido, puedes entender que los pesos significan tiempo y te están pidiendo que encuentres una ruta en la que se inviertan 84 minutos.

Para orientarse en un grafo hay que usar algoritmos de encaminamiento. Estos algoritmos permiten calcular rutas más o menos óptimas entre dos puntos cualesquiera del grafo.

En cualquier caso estos algoritmos suelen hacer uso intensivo de listas y árboles, ya que suelen tantear varias rutas antes de elegir la que creen más óptima.

He sacado un ratillo y me ha picado el gusanillo. Un código que navega por un grafo y busca una ruta con el peso pedido:

Código C++:
Ver original
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. struct Posicion
  6. {
  7.   size_t fila;
  8.   size_t columna;
  9.  
  10.   Posicion(size_t fila, size_t columna)
  11.     : fila(fila),
  12.       columna(columna)
  13.   { }
  14.  
  15.   bool operator==(const Posicion& otra) const
  16.   {
  17.     return (fila == otra.fila) && (columna == otra.columna);
  18.   }
  19. };
  20.  
  21. using Ruta = std::vector<Posicion>;
  22.  
  23. class Grafo
  24. {
  25.     std::vector<int> _valores;
  26.     size_t _numFilas;
  27.     size_t _numColumnas;
  28.  
  29.   public:
  30.     Grafo(size_t filas, size_t columnas, int* valores)
  31.       : _numFilas(filas),
  32.         _numColumnas(columnas)
  33.     {
  34.       // Copiamos los datos en el grafo
  35.       _valores.reserve(filas*columnas);
  36.       for( size_t i=filas*columnas; i>0; --i)
  37.       {
  38.         _valores.push_back(*valores);
  39.         ++valores;
  40.       }
  41.     }
  42.  
  43.     size_t NumFilas() const
  44.     { return _numFilas; }
  45.  
  46.     size_t NumColumnas() const
  47.     { return _numColumnas; }
  48.  
  49.     int Valor(const Posicion& posicion) const
  50.     { return _valores[posicion.fila * _numColumnas + posicion.columna]; }
  51. };
  52.  
  53. // Verifica que la nueva posición es válida.
  54. // Se entiende que es válida si está dentro de los límites del grafo
  55. // y si la posición no ha sido usada.
  56. bool PosicionValida(
  57.     const Grafo& grafo,
  58.     const Ruta& ruta,
  59.     const Posicion& nuevaPosicion)
  60. {
  61.   auto toReturn = (nuevaPosicion.fila < grafo.NumFilas());
  62.  
  63.   if( toReturn )
  64.     toReturn = (nuevaPosicion.columna < grafo.NumColumnas());
  65.  
  66.   if( toReturn )
  67.   {
  68.     auto it = std::find(ruta.begin(),ruta.end(),nuevaPosicion);
  69.     toReturn = (it == ruta.end());
  70.   }
  71.  
  72.   return toReturn;
  73. }
  74.  
  75. bool BuscarRuta(
  76.     const Grafo& grafo,
  77.     const Posicion& nuevaPosicion,
  78.     const Posicion& destino,
  79.     Ruta& ruta,
  80.     int pesoActual,
  81.     int pesoEsperado)
  82. {
  83.   auto toReturn = false;
  84.  
  85.   if( PosicionValida(grafo,ruta,nuevaPosicion) )
  86.   {
  87.     ruta.push_back(nuevaPosicion);
  88.     auto nuevoPeso = grafo.Valor(nuevaPosicion);
  89.     pesoActual += nuevoPeso;
  90.  
  91.     if( nuevaPosicion == destino )
  92.       toReturn = pesoActual == pesoEsperado;
  93.     else if( pesoActual >= pesoEsperado )
  94.       toReturn = false;
  95.     else
  96.     {
  97.       //  Intentamos avanzar hacia arriba
  98.       auto nueva = Posicion(nuevaPosicion.fila-1,nuevaPosicion.columna);
  99.       toReturn = BuscarRuta(grafo,nueva,destino,ruta,pesoActual,pesoEsperado);
  100.  
  101.       if( !toReturn )
  102.       {
  103.         // Intentamos avanzar hacia la derecha
  104.         auto nueva = Posicion(nuevaPosicion.fila,nuevaPosicion.columna+1);
  105.         toReturn = BuscarRuta(grafo,nueva,destino,ruta,pesoActual,pesoEsperado);
  106.       }
  107.  
  108.       if( !toReturn )
  109.       {
  110.         // Intentamos avanzar hacia abajo
  111.         auto nueva = Posicion(nuevaPosicion.fila+1,nuevaPosicion.columna);
  112.         toReturn = BuscarRuta(grafo,nueva,destino,ruta,pesoActual,pesoEsperado);
  113.       }
  114.  
  115.       if( !toReturn )
  116.       {
  117.         // Intentamos avanzar hacia la izquierda
  118.         auto nueva = Posicion(nuevaPosicion.fila,nuevaPosicion.columna-1);
  119.         toReturn = BuscarRuta(grafo,nueva,destino,ruta,pesoActual,pesoEsperado);
  120.       }
  121.     }
  122.  
  123.     if( !toReturn )
  124.     {
  125.       // Si no se ha encontrado una ruta válida se borra la posición
  126.       // que hemos registrado al inicio de la función
  127.       ruta.pop_back();
  128.       pesoActual -= nuevoPeso;
  129.     }
  130.   }
  131.  
  132.   return toReturn;
  133. }
  134.  
  135. int main()
  136. {
  137.   int valores[] = {6, 1, 9, 2, 4, 5,
  138.                    3, 7, 1, 5, 5, 9,
  139.                    5, 3, 4, 8, 7, 1,
  140.                    1, 3, 1, 4, 5, 3,
  141.                    3, 4, 8, 9, 2, 7};
  142.  
  143.   auto grafo = Grafo(5, 6, valores);
  144.  
  145.   auto posActual = Posicion(4,5);
  146.   auto posFinal = Posicion(4,0);
  147.   Ruta ruta;
  148.  
  149.   BuscarRuta(grafo,posActual,posFinal,ruta,0,48);
  150.  
  151.   if( ruta.empty() )
  152.     std::cout << "No se ha encontrado ninguna ruta" << std::endl;
  153.   else
  154.   {
  155.     std::cout << "Ruta encontrada:" << std::endl;
  156.     for( auto posicion : ruta )
  157.       std::cout << "(" << posicion.fila << "," << posicion.columna << ")" << std::endl;
  158.   }
  159.  
  160.   return EXIT_SUCCESS;
  161. }

PD.: el algoritmo encuentra una ruta alternativa a la que has encontrado tu :)
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 13/01/2016 a las 04:57
  #5 (permalink)  
Antiguo 13/01/2016, 16:06
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

Me quedo asombrado con lo que has puesto ya que yo solo he llegado a las listas simples, ni siquiera he visto aún los árboles y me pierdo en lo que pusiste.
Para empezar no comprendo lo que haces en la estructura que pones el ¿prototipo de la función posición? Se llama igual que la estructura ¿es como un constructor o algo así como con las clases. Además hay dos puntos y más cosas tras ellos que tampoco entiendo.
Otra cosa que me ha llamado la atención es que usas un tipo llamado "auto" ¿ese que tipo es?
Bueno hay muchas más cosas pero esas me han dejado descolocado.
  #6 (permalink)  
Antiguo 14/01/2016, 00:44
 
Fecha de Ingreso: septiembre-2006
Ubicación: Buenos Aires
Mensajes: 125
Antigüedad: 17 años, 7 meses
Puntos: 0
Respuesta: Necesito orientacion con el siguiente codigo

Una forma muy poco eficiente y bruta seria hacer un algoritmo que al azar vaya adelante izquierda o derecha y memorizar los nodos donde estuvo (para no volver al mismo nodo) e ir sumando hasta que llegue de casualidad al final. y ver si es el resultado deseado y si no cumple volver a iterar hasta que la suma sea el numero deseado.

hay nodos donde solo puede tomar 3 direcciones ,otros 2 direcciones y en las esquinas 1 sola dirección.

Si el problema aumentaria en nodos nodos la PC puede estar horas hasta llegar de casualidad al resultado, con este método que les comento.


Saludos
__________________
alquiler gesell
  #7 (permalink)  
Antiguo 14/01/2016, 01:25
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Necesito orientacion con el siguiente codigo

Cita:
Iniciado por aguml Ver Mensaje
Para empezar no comprendo lo que haces en la estructura que pones el ¿prototipo de la función posición? Se llama igual que la estructura ¿es como un constructor o algo así como con las clases. Además hay dos puntos y más cosas tras ellos que tampoco entiendo.
Código C++:
Ver original
  1. struct Posicion
  2. {
  3.   size_t fila;
  4.   size_t columna;
  5.  
  6.   Posicion(size_t fila, size_t columna)
  7.     : fila(fila),
  8.       columna(columna)
  9.   { }
  10.  
  11.   bool operator==(const Posicion& otra) const
  12.   {
  13.     return (fila == otra.fila) && (columna == otra.columna);
  14.   }
  15. };

En C++, la única diferencia entre struct y class es que por defecto (es decir, si no se indica algo explícitamente) el acceso a sus miembros es público en struct y privado en class. En todo lo demás son exactamente iguales: aceptan herencia (ya sea de struct o de class), polimorfismo, usan constructores, admiten la sobrecarga de operadores, ...

En el caso que comentas:

Código C++:
Ver original
  1. Posicion(size_t fila, size_t columna)
  2.     : fila(fila),
  3.       columna(columna)
  4. { }

Se refiere a un constructor para objetos de tipo Posicion. Los que ves tras los dos puntos son inicializaciones de variables. Lo anterior es similar (que no necesariamente idéntico) a lo siguiente:

Código C++:
Ver original
  1. Posicion(size_t fila, size_t columna)
  2. {
  3.   this->fila = fila;
  4.   this->columna = columna;
  5. }

La diferencia principal se encuentra en la cantidad de incializaciones que recibe cada variable. En el primer código se llama al constructor copia de la variable, mientras que en el segundo se llama primero al constructor por defecto y después se hace una asignación. Si trabajas con objetos en vez de con tipos primitivos el segundo ejemplo suele ser más costoso.

Un detalle que puede llamar la atención es que en el primer código no hace falta usar this y en el segundo sí. Esto se debe a que el compilador en este caso es un pelín inteligente y sabe que estoy inicializando la clase, luego únicamente me va a dejar inicializar miembros de la clase. Para el compilador es como si hubiésemos escrito algo tal que:

Código C++:
Ver original
  1. Posicion(size_t f, size_t c)
  2.     : fila(f),
  3.       columna(c)
  4. { }

¿Por qué uso un struct aquí? por comodidad. No tengo ninguna necesidad de hacer que sus variables internas sean privadas, creando un struct me ahorro tener que poner public:

Cita:
Iniciado por aguml Ver Mensaje
Otra cosa que me ha llamado la atención es que usas un tipo llamado "auto" ¿ese que tipo es?
Llegados a este punto toca ir revisando las modificaciones que se introdujeron con el estándar C++11. Bien es cierto que el estándar de C++ lleva muuuuchos años parado, pero ahora ha empezado a coger carrerilla. Prueba de ello es que ya tenemos dos estándares nuevos (C++11 y C++14) y otro en camino (C++17).

auto es una palabra reservada que se introdujo en C++11. auto permite declarar variables, la única cosa es que no eliges tu el tipo de la variable, sino que encargas al compilador la tarea de "deducir" el tipo.

Parece algo chorra pero es muy útil. Imagínate un programita completo y te toca cambiar el tipo que devuelve una función. Usando la forma tradicional tendrías que buscar todos los usos de la función y cambiar el tipo de la variable en multitud de sitios... con auto simplemente recompilas y es el compilador el que se encarga de esa tarea.

Cita:
Iniciado por aguml Ver Mensaje
Bueno hay muchas más cosas pero esas me han dejado descolocado.
Pues no te cortes y pregunta, que para eso estamos aquí ;)

Cita:
Iniciado por acknowledge
Una forma muy poco eficiente y bruta seria hacer un algoritmo que al azar vaya adelante izquierda o derecha y memorizar los nodos donde estuvo (para no volver al mismo nodo) e ir sumando hasta que llegue de casualidad al final. y ver si es el resultado deseado y si no cumple volver a iterar hasta que la suma sea el numero deseado.
Tu has escrito una respuesta sin leer lo que ya estaba escrito, verdad?

La solución que he puesto sigue exactamente ese ineficiente camino... pero oye, para haber sacado el programa en media hora no está mal del todo, no? :)

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #8 (permalink)  
Antiguo 14/01/2016, 05:46
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

La verdad es que no sabia que las estructuras eran tan parecidas a las clases. Yo pensaba que el tema de constructores, polimorfismo y herencia era exclusivo de las clases. Además pensaba que esos dos puntos era como en las clases que se usa para indicar de cual clase deriva (no se si es correcto lo que digo). O sea:
class ClaseDerivada : public ClaseBase
Lo que no entiendo es que en este caso lo que hace es llamar a la función fila y columna que no veo declaradas en ningún sitio y que me hace pensar que es algún tipo de constructores así que entonces deduzco que size_t ¿es una estructura o una clase? Esa línea me deja en fuera de juego jejeje.
  #9 (permalink)  
Antiguo 14/01/2016, 07:12
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Necesito orientacion con el siguiente codigo

Cita:
Iniciado por aguml Ver Mensaje
Además pensaba que esos dos puntos era como en las clases que se usa para indicar de cual clase deriva (no se si es correcto lo que digo). O sea:
class ClaseDerivada : public ClaseBase
Los dos puntos tienen varios usos, depende de dónde se encuentre cumple una función u otra. En el caso de declarar una herencia, esta declaración únicamente puede hacerse nada más poner el nombre de la clase, luego su uso es bastante restringido.

Una cosa que no te he comentado de usar los dos puntos en el constructor es que es el único mecanismo que te permite invocar un constructor específico del padre... en el caso de herencias, claro.

Código C++:
Ver original
  1. class Padre
  2. {
  3.   public:
  4.     Padre(int algo);
  5. };
  6.  
  7. class Hija : public Padre
  8. {
  9.   public:
  10.     Hija()
  11.       : Padre(5) // Invocamos al constructor Padre(int)
  12.    { }
  13. };

Cita:
Iniciado por aguml Ver Mensaje
Lo que no entiendo es que en este caso lo que hace es llamar a la función fila y columna que no veo declaradas en ningún sitio
Fíjate bien en el código.

Código C++:
Ver original
  1. struct Posicion
  2. {
  3.   // Están declaradas AQUI!!!!
  4.   size_t fila;
  5.   size_t columna;
  6.  
  7.   Posicion(size_t fila, size_t columna)
  8.     : fila(fila),
  9.       columna(columna)
  10.   { }
  11. };

En el constructor estoy incializando variables miembro, no variables locales, luego dichas variables tienen que estar declaradas en la clase, no en el constructor.

Cita:
Iniciado por aguml Ver Mensaje
size_t ¿es una estructura o una clase?
size_t es un alias, es decir, un typedef. Se usa muchísimo en la STL y, si no te lo crees, mira lo que te devuelve X.size() (sustituye X por un contenedor cualquiera, incluso la clase string).

¿Por qué usar un alias en estos casos? Pues porque el tipo al que referencia el alias puede variar de un sistema a otro. Esto permite que el programa se comporte igual independientemente de la plataforma sobre la que se ejecute.

Vamos a poner un ejemplo concreto para que esto último quede más claro.

Imagínate que en tu programa esperas que un tipo de dato sea un entero de 32 bits... lo primero que puedes pensar es "uso el tipo int que son 32 bits. Eso funcionaría hasta que te topas con un sistema que al int le asigna únicamente 16 bits. Ahora si tu en vez de usar int usas un alias, pongamos int_32 y te preocupas de que ese alias apunte a int en un caso y a long en otro, pues ya tienes el problema resuelto sin tener que tocar todo el código.

PD.: para obtener tipos de tamaño conocido (8 bits, 32 bits, etc), existe la cabecera [i]stdint[/h] que te proporciona unos cuantos. Más información aquí.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #10 (permalink)  
Antiguo 14/01/2016, 13:02
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

Pero no entiendo esto:
fila(fila),
columna(columna)
Sí size_t es un alias de int32 ¿como es que lo usas como una función?
  #11 (permalink)  
Antiguo 14/01/2016, 13:42
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Necesito orientacion con el siguiente codigo

Al tener el constructor de la manera que eferion hace que a la variable del struct Posicion fila se inicialize con el valor del parámetro fila, y la variable con nombre columna se inicialize con el valor de columna. Una definición formal de dicha manera de inicializar datos llamada lista de inicialización y algunos ejemplos

Código C++:
Ver original
  1. struct definicion_formal {
  2.   int variable1;
  3.   int variable2;
  4.   // Constructor sin parámetros. Inicializa variable1 a 0 y variable2 a 50
  5.   definicion_formal() : variable1(0), variable2(50) {}
  6.   // Constructor con parámetros. Inicializa variable1 con el valor de a y variable2 con el valor de b
  7.   definicion_formal(int a, int b) : variable1(a), variable2(b);
  8. };
  9. // Por tanto si ahora declaro
  10. int main() {
  11.   definicion_formal ejemplo1; // Ejemplo 1 tiene variable1 a 0 y variable2 a 50
  12.   definicion_formal ejemplo2(3, 4); // Ejemplo 2 tiene variable1 a 3 y variable2 a 4
  13. }

En cuanto lo de size_t, como te dijo eferion size_t es un alias usando ampliamente por las estructuras de datos en C++ para indicar el tamaño de una estructura, en concreto es un tipo de unsigned int que debería ser capaz de almacenar el tamaño máximo de una estructura. En ningún momento es llamado como función siempre es usado como indicador del tipo.

Espero haber ayudado a que lo comprendas mejor.
  #12 (permalink)  
Antiguo 14/01/2016, 17:06
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

Cuando digo que parece usarlo como función me refiero a esto que haces:
variable1(a)
En tu caso variable1 es un int pero esa línea yo la interpreto como:
int variable1 (int a)
A eso me refiero y no lo entiendo. Supongo que será algo que no he dado aun y que tendrá que ver con herencias o cosas de esas pero para mi un nombre con un paréntesis tal y como aparece, hasta donde yo llego es una función.
  #13 (permalink)  
Antiguo 14/01/2016, 17:28
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Necesito orientacion con el siguiente codigo

Es una llamada al constructor, en realidad no es más que una forma abreviada de hacer lo siguiente:

Código C++:
Ver original
  1. struct definicion_formal {
  2.   int variable1;
  3.   int variable2;
  4.   // Constructor sin parámetros. Inicializa variable1 a 0 y variable2 a 50
  5.   definicion_formal() {
  6.     variable1 = 0;
  7.     variable2 = 50;
  8.   }
  9.   // Constructor con parámetros. Inicializa variable1 con el valor de a y variable2 con el valor de b
  10.   definicion_formal(int a, int b) {
  11.     variable1 = a;
  12.     variable2 = b;
  13. };
  14. // Por tanto si ahora declaro
  15. int main() {
  16.   definicion_formal ejemplo1; // Ejemplo 1 tiene variable1 a 0 y variable2 a 50
  17.   definicion_formal ejemplo2(3, 4); // Ejemplo 2 tiene variable1 a 3 y variable2 a 4
  18. }

Un ejemplo todavía más simple:
Código C++:
Ver original
  1. int i(5); // i se inicializa a 5
  2. int j = 5; // j se inicializa a true
  3. bool correcto(i==j); // correcto se inicializa a true
  4. bool falso = i != j; // falso se inicializa a false
  #14 (permalink)  
Antiguo 15/01/2016, 03:33
 
Fecha de Ingreso: septiembre-2006
Ubicación: Buenos Aires
Mensajes: 125
Antigüedad: 17 años, 7 meses
Puntos: 0
Respuesta: Necesito orientacion con el siguiente codigo

Eferion: lei lo escrito , mire rápido tu codigo y no vi la parte aleatoria o al azar.
yo lo que proponia es hacer un camino totalmente aleatorio y si el camino se cruza empezar de nuevo asì se escribe menos codigo (y es super ineficiente), si llega al final de casualidad calcular el valor.

Si tu código funcionò esta mas que bien

Saludos
__________________
alquiler gesell
  #15 (permalink)  
Antiguo 15/01/2016, 04:14
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Necesito orientacion con el siguiente codigo

Cita:
Iniciado por acknowledge Ver Mensaje
yo lo que proponia es hacer un camino totalmente aleatorio y si el camino se cruza empezar de nuevo asì se escribe menos codigo (y es super ineficiente), si llega al final de casualidad calcular el valor.
Hombre, calculando ruta al azar podrías ahorrarte en mi programa digamos... unas 17 líneas (contando comentarios, líneas en blanco y llaves, que las suelo poner en línea independiente)... porque claro tienes que añadir la lógica para generar los aleatorios (20 líneas de código a eliminar - 1 para inicializar random - 1 para generar desplazamiento X - 1 para generar desplazamiento Y).

Creo que el ahorro en líneas tampoco es excesivo aunque en términos estrictos debo darte la razón en todo:

SI son menos líneas
SI es muuuucho más ineficiente jejeje

Cita:
Iniciado por aguml Ver Mensaje
Cuando digo que parece usarlo como función me refiero a esto que haces:
variable1(a)
En tu caso variable1 es un int pero esa línea yo la interpreto como:
int variable1 (int a)
A eso me refiero y no lo entiendo. Supongo que será algo que no he dado aun y que tendrá que ver con herencias o cosas de esas pero para mi un nombre con un paréntesis tal y como aparece, hasta donde yo llego es una función.
Echa un vistazo al siguiente ejemplo:

La clase Variable saca por pantalla varios mensajes cuando se llama a sus diferentes funciones.

Después creamos dos clases Clase1 y Clase2. La primera inicializa su instancia de Variable con una asignación, mientras que Clase2 usa los inicializadores en el constructor.

Código C++:
Ver original
  1. struct Variable
  2. {
  3.    Variable(){ std::cout << "Variable::Variable()" << std::endl; }
  4.  
  5.    Variable(int valor)
  6.    { std::cout << "Variable::Variable(int)" << std::endl; }
  7.  
  8.    void operator=(int valor)
  9.    { std::cout << "Variable::operator=()" << std::endl; }
  10. };
  11.  
  12. class Clase1
  13. {
  14.    Variable v;
  15.   public:
  16.     Clase1()
  17.     {
  18.       v = 5;
  19.     }
  20. };
  21.  
  22. class Clase2
  23. {
  24.    Variable v;
  25.  
  26.   public:
  27.     Clase2()
  28.       : v(5)
  29.     {
  30.     }
  31. };
  32.  
  33. int main()
  34. {
  35.   std::cout << "Clase1 llama a dos funciones" << std::endl;
  36.   Clase1 c1;
  37.  
  38.   std::cout << std::endl;
  39.   std::cout << "Clase2 unicamente llama a una funcion" << std::endl;
  40.   Clase2 c2;
  41.   std::cout << std::endl;
  42. }

El resultado es claro. Si se hacen asignaciones se acaban ejecutando dos funciones (constructor por defecto y operador de asignación), mientras que si usamos los inicializadores únicamente se hace una llamada al constructor que corresponda. Esta segunda opción suele ser más eficiente al usar clases ya que aparte de ahorrarnos la llamada a una función nos podemos ahorrar pasos innecesarios (como inicializar una variable a 0 en el constructor por defecto para un instante después asignarle un valor diferente con el operador de asignación).

Espero que te haya quedado este punto más claro con el ejemplo.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 15/01/2016 a las 04:27
  #16 (permalink)  
Antiguo 15/01/2016, 04:28
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

Cita:
Iniciado por xKuZz Ver Mensaje
Es una llamada al constructor, en realidad no es más que una forma abreviada de hacer lo siguiente:

Código C++:
Ver original
  1. struct definicion_formal {
  2.   int variable1;
  3.   int variable2;
  4.   // Constructor sin parámetros. Inicializa variable1 a 0 y variable2 a 50
  5.   definicion_formal() {
  6.     variable1 = 0;
  7.     variable2 = 50;
  8.   }
  9.   // Constructor con parámetros. Inicializa variable1 con el valor de a y variable2 con el valor de b
  10.   definicion_formal(int a, int b) {
  11.     variable1 = a;
  12.     variable2 = b;
  13. };
  14. // Por tanto si ahora declaro
  15. int main() {
  16.   definicion_formal ejemplo1; // Ejemplo 1 tiene variable1 a 0 y variable2 a 50
  17.   definicion_formal ejemplo2(3, 4); // Ejemplo 2 tiene variable1 a 3 y variable2 a 4
  18. }

Un ejemplo todavía más simple:
Código C++:
Ver original
  1. int i(5); // i se inicializa a 5
  2. int j = 5; // j se inicializa a true
  3. bool correcto(i==j); // correcto se inicializa a true
  4. bool falso = i != j; // falso se inicializa a false
Gracias por la explicación y decir que en ningún sitio vi que expliquen este modo de inicializar variables. ¿eso vale para C también o es solo a partir de alguna revisión de c++?
Otra cosa que no se que hace es esto:
using Ruta = std::vector<Posicion>;
¿que hace exactamente?
Otra cosa ¿el código que puso eferion hacia:
fila (fila)
Y me dices que eso equivaldría a inicializar la variable asi:
fila=fila
Donde la primera seria una variable miembro de la estructura y la segunda seria un parámetro pero en ambos casos se llama igual la variable y tenia entendido que eso no estaba permitido ¿podéis explicarme eso también?
Otra duda que tengo del código de eferion es si siempre daría la misma solución o cambiaría en cada ejecución. Si siempre da la misma me interesaría hacer que ese código me diera todas las soluciones correctas.
Teniendo esos temas resueltos es cuestión de tracear e intentar entender su funcionamiento.
Gracias a todos.

Última edición por aguml; 15/01/2016 a las 04:45
  #17 (permalink)  
Antiguo 15/01/2016, 05:04
 
Fecha de Ingreso: septiembre-2010
Mensajes: 494
Antigüedad: 13 años, 7 meses
Puntos: 10
Respuesta: Necesito orientacion con el siguiente codigo

Cita:
Iniciado por aguml Ver Mensaje
Gracias por la explicación y decir que en ningún sitio vi que expliquen este modo de inicializar variables. ¿eso vale para C también o es solo a partir de alguna revisión de c++?
Otra cosa que no se que hace es esto:
using Ruta = std::vector<Posicion>;
¿que hace exactamente?
Otra cosa ¿el código que puso eferion hacia:
fila (fila)
Y me dices que eso equivaldría a inicializar la variable asi:
fila=fila
Donde la primera seria una variable miembro de la estructura y la segunda seria un parámetro pero en ambos casos se llama igual la variable y tenia entendido que eso no estaba permitido ¿podéis explicarme eso también?
Otra duda que tengo del código de eferion es si siempre daría la misma solución o cambiaría en cada ejecución. Si siempre da la misma me interesaría hacer que ese código me diera todas las soluciones correctas.
Teniendo esos temas resueltos es cuestión de tracear e intentar entender su funcionamiento.
Gracias a todos.
Hola aguml:

Sobre la forma de inicializar variables en el constructor esto te puede ayudar:
http://c.conclase.net/curso/index.php?cap=029#inicio

(en concreto el apartado "Inicialización de objetos")
__________________
Mi calculadora en Qt
  #18 (permalink)  
Antiguo 15/01/2016, 05:10
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 6 meses
Puntos: 204
Respuesta: Necesito orientacion con el siguiente codigo

Cita:
Iniciado por aguml Ver Mensaje
¿eso vale para C también o es solo a partir de alguna revisión de c++?
C no es orientado a objetos. Las estructuras son simplemente paquetes de datos sin ningún tipo de lógica de funciones por medio.

Cita:
Iniciado por aguml Ver Mensaje
Otra cosa que no se que hace es esto:
Código C++:
Ver original
  1. using Ruta = std::vector<Posicion>;
¿que hace exactamente?
Es equivalente a

Código C++:
Ver original
  1. typedef std::vector<Posicion> Ruta;

Como te comenté, interesa estar al tanto de las novedades que traen los nuevos estándares. Esta en concreto aparece por primera vez en C++11.

Cita:
Iniciado por aguml Ver Mensaje
Otra cosa ¿el código que puso eferion hacia:
fila (fila)
Y me dices que eso equivaldría a inicializar la variable asi:
fila=fila
Donde la primera seria una variable miembro de la estructura y la segunda seria un parámetro pero en ambos casos se llama igual la variable y tenia entendido que eso no estaba permitido ¿podéis explicarme eso también?
Código C++:
Ver original
  1. POO::POO(int valor)
  2.   : valor(valor)
  3. { }

En el ejemplo anterior, el primer valor se ha de referir sí o sí a un miembro de POO ya que estás inicializando la clase (así es como funciona este apartado del constructor. En el segundo valor sí que tendríamos un solapamiento (la variable pasada como parámetro y la variable miembro). En este caso la ambigüedad desaparece porque no estamos usando this->valor, que sería el código que tendríamos que poner para usar la variable miembro. Como no se pone lo anterior el compilador entiende que estamos haciendo uso de la variable pasada como argumento.

¿Por qué? La regla que sigue el compilador en caso de solapamiento de variables es elegir aquella que tiene un menor ámbito. En el caso que nos ocupa, la variable miembro vive mientras exista el objeto mientras que el argumento únicamente vive dentro del constructor. El ámbito de la variable miembro puede que no esté definido claramente, pero desde luego es mucho mayor que el del argumento, luego en caso de conflicto el compilador va a elegir el argumento.

Lo que el compilador no tolera es que dos variables con el mismo ámbito se llamen igual. Dicho con un ejemplo:

Código C++:
Ver original
  1. int main()
  2. {
  3.   // Todas las versiones de 'a' son válidas
  4.   int a = 0;
  5.   std::cout << a; // 0
  6.   {
  7.     int a = 1;
  8.     std::cout << a; // 1
  9.     {
  10.       int a = 2;
  11.       std::cout << a; // 2
  12.     }
  13.     std::cout << a; // 1; a=2 ya no existe
  14.   }
  15.   std::cout << a; // 0; a=1 ya no existe
  16.  
  17.   int b;
  18.   int b; // Esta línea da error, ya hay una variable llamada 'b' con el mismo ámbito.
  19. }

Cita:
Iniciado por aguml Ver Mensaje
Otra duda que tengo del código de eferion es si siempre daría la misma solución o cambiaría en cada ejecución.
El algoritmo se para con la primera solución que encuentra y ésta siempre va a ser la misma.

Cita:
Iniciado por aguml Ver Mensaje
Si siempre da la misma me interesaría hacer que ese código me diera todas las soluciones correctas.
Eso ya requiere algo más de trabajo dentro del algoritmo. Intenta adaptar el código para que cumpla esa nueva tarea.

Yo empezaría por cambiar el retorno de la función, debería devolver una lista de rutas en vez de una única ruta.

Un saludo.
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.
  #19 (permalink)  
Antiguo 15/01/2016, 09:15
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

Pues yo el único uso que conocía para using es:
using namespace...
¿que ventajas tiene usar using en tu caso con respecto de usar typedef?
Por lo demás, para entender bien como funciona tu codigo, en cuanto tenga tiempo me pondré a tracearlo paso a paso y una vez lo entienda ya podre intentar modificarlo para conseguir lo que deseo.
Muchas gracias.
  #20 (permalink)  
Antiguo 15/01/2016, 10:09
Avatar de xKuZz  
Fecha de Ingreso: febrero-2015
Ubicación: nullptr
Mensajes: 183
Antigüedad: 9 años, 2 meses
Puntos: 27
Respuesta: Necesito orientacion con el siguiente codigo

Por regla general, el uso de typedef o using para declarar un alias de un tipo hace exactamente lo mismo. La única ventaja que tiene utilizar using es que te permite hacer alias en templates (plantillas), mientras que typedef no, ejemplo:

Código C++:
Ver original
  1. template <typename T>
  2. class clase_parametrizada {
  3.   T dato;
  4. };
  5.  
  6. template <typename T>
  7. typedef clase_parametrizada<T> un_alias; // Error en tiempo de compilación. Typedef no puede ser una plantilla.
  8.  
  9. template <typename T>
  10. using un_alias = clase_parametrizada<T>; // Funciona perfectamente
  11.  
  12. // A partir de ahora escribir un_alias<T> es lo mismo que escribir clase_parametrizada<T>

Aparte del uso para alias que acabo de mostrarte using también sirve para definiciones y declaraciones de namespaces como el clásico using namespace std; y también tiene usos interesantes en cuestiones de herencia, pero eso mejor lo dejamos para más adelante
  #21 (permalink)  
Antiguo 15/01/2016, 17:24
 
Fecha de Ingreso: febrero-2015
Mensajes: 404
Antigüedad: 9 años, 2 meses
Puntos: 3
Respuesta: Necesito orientacion con el siguiente codigo

Muchas gracias por todo. Cuando pueda lo tracearé y si hay algo que no entienda os pregunto

Etiquetas: int, orientacion, siguiente
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 23:27.