elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: (TUTORIAL) Aprende a emular Sentinel Dongle By Yapis


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Ayuda con Recursividad
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda con Recursividad  (Leído 1,431 veces)
40

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Ayuda con Recursividad
« en: 13 Septiembre 2015, 05:42 am »

Estoy empezando a ver recursividad y trato de realizar este problema: "Un autobus sale lleno con 50 pasajeros; a lo largo de su trayectoria bajan y suben los pasajeros.
En la primer parada bajan 5 y suben 2, en la segunda parada bajan 3 y suben 4, en la tercer parada
bajan 10 y suben 5, en la cuarta parada bajan 8 y suben 5 y en la quinta parada bajan 2 y suben 2. Hacer un programa usando recursividad que nos muestre cuantos pasajeros subieron en total y cuantos pasajeros bajaron en total."

Esto es lo que tengo
Código
  1. class Program
  2.    {
  3.        static int Camion(int parada, int suben, int bajan)
  4.        {
  5.            int parad= parada+1;
  6.            parad++;
  7.            int s = suben;
  8.            int b = bajan;
  9.            if (parad == 1)
  10.            {
  11.                return Camion(parad, s + 2, b + 3);
  12.            }
  13.            else
  14.            {
  15.                if (parad == 2)
  16.                {
  17.                    return Camion(parad, s + 4, b + 8);
  18.                }
  19.  
  20.                else
  21.                {
  22.                    if (parad == 3)
  23.                    {
  24.                        return Camion(parad, s + 5, b + 10);
  25.                    }
  26.                    else
  27.                    {
  28.                        if (parad == 4)
  29.                        {
  30.                            return Camion(parad, s + 5, b + 8);
  31.                        }
  32.                        else
  33.                        {
  34.                            if (parad == 5)
  35.                            {
  36.                                return Camion(parad, s + 2, b + 2);
  37.                            }
  38.                            else
  39.                                Console.WriteLine(Camion(parad, s, b));
  40.                        }
  41.                    }
  42.                }
  43.            }
  44.        }
  45.        static void Main(string[] args)
  46.        {
  47.            Console.WriteLine(Camion(0,0,0));
  48.            Console.ReadKey();
  49.        }
  50.    }
  51. }

Me falla en querer imprimir los valores  :-\ y no encuentro el fallo  :(
De antemano muchas gracis :)



[Engel Lex]: Mod los codigo van etiquetas GeSHi, los temas de programacion van en sus respectivos subforos, no puedes esperar que adivinemos en que lenguaje esta tu programa... Avisa en que lenguaje está para moverlo y corregirlo!

[Elektro]: Sigue las indicaciones del compañero @Engel Lex. Debes publicar los códigos de C# en el subforo dedicado a la plataforma .Net, no en "Dudas generales"...


« Última modificación: 13 Septiembre 2015, 08:39 am por Eleкtro » En línea

Eleкtro
Ex-Staff
*
Desconectado Desconectado

Mensajes: 9.708



Ver Perfil
Re: Ayuda con Recursividad
« Respuesta #1 en: 13 Septiembre 2015, 11:41 am »

El problema precisamente es la recursividad, no se en que página web o que profesor te ha mandado el ejercicio, pero es una metodología que se debe evitar sin excepción alguna, a menos que simplemente sea para aprender el concepto de recursividad y ya está (aunque en mi humilde opinión de nada sirve aprender eso).

En este caso en particular, la función Camion hace miles y miles de llamadas a si misma y cómo resultado da una sobrecarga en la pila, lanzando como consecuencia una esperada excepción de tipo StackOverflowException.

Ten en cuenta que son 5 paradas, sabiendo ese factor del problema entonces obviamente la función debería hacer solamente 5 llamadas a si misma, no miles :P.

Aparte de eso, cometes un fallo en el algoritmo el cual provoca una recursividad infinita (que es lo que provoca la excepción) y estás usando ifs anidados cuando puedes usar else if, o un switch.

Pero mi único consejo es ese, que no hagas ese tipo de funciones recursivas en la vida real, ya que son innecesarias en cualquier caso y solo conllevan problemas de este tipo, no se aprende nada de utilidad bajo mi punto de vista. Puedes convertir cualquier función recursiva en función iterativa con el uso de los búcles (for, while, etc dependiendo de las circunstancias)

En fin, aquí tienes el ejercicio funcional (con recursión):

VB.Net:
Código
  1. Module Module1
  2.  
  3.    Sub Main()
  4.  
  5.        Dim passengers As Integer = 50
  6.        Dim result As KeyValuePair(Of Integer, Integer) = BusPassengers(passengers)
  7.  
  8.        Console.WriteLine()
  9.        Console.WriteLine(String.Format("{0,-22} | {1,-22} | {2}",
  10.                                        "Remaining passengers", "Pas. that left out", "Pas. that entered into"))
  11.        Console.WriteLine()
  12.  
  13.        Console.WriteLine(String.Format("{0,-22}   {1,-22}   {2}",
  14.                                        passengers.ToString("00"), result.Key.ToString("00"), result.Value.ToString("00")))
  15.        Console.ReadKey()
  16.  
  17.    End Sub
  18.  
  19.    ''' ----------------------------------------------------------------------------------------------------
  20.    ''' <summary>
  21.    ''' </summary>
  22.    ''' ----------------------------------------------------------------------------------------------------
  23.    ''' <param name="passengers">
  24.    ''' The initial amount of passengers that are inside the bus.
  25.    ''' </param>
  26.    ''' ----------------------------------------------------------------------------------------------------
  27.    ''' <returns>
  28.    ''' An <see cref="KeyValuePair(Of Integer, Integer)"/> instance where the
  29.    ''' <see cref="KeyValuePair.Key"/> property contains the total amount of passengers that left out the bus, and the
  30.    ''' <see cref="KeyValuePair.Value"/> property contains the total amount of passengers that entered into the bus.
  31.    ''' </returns>
  32.    ''' ----------------------------------------------------------------------------------------------------
  33.    Private Function BusPassengers(ByRef passengers As Integer) As KeyValuePair(Of Integer, Integer)
  34.  
  35.        ' Bus-Stop count.
  36.        Static stops As Integer = 0
  37.        stops += 1
  38.  
  39.        ' Current amount of passengers that left out the bus in the current bus-stop.
  40.        Static goOut As Integer
  41.  
  42.        ' Current amount of passengers that entered into the bus in the current bus-stop.
  43.        Static goIn As Integer
  44.  
  45.        ' Total amount of passengers that left out the bus.
  46.        Static goOutTotal As Integer
  47.        goOutTotal += goOut
  48.  
  49.        ' Total amount of passengers that entered into the bus.
  50.        Static goInTotal As Integer
  51.        goInTotal += goIn
  52.  
  53. #If DEBUG Then
  54.  
  55.        If (stops = 1) Then
  56.            Console.WriteLine(String.Format("{0,-16} | {1,-16} | {2,-16} | {3}",
  57.                                            "Stop count", "Passengers Out", "Passengers In", "Total passengers"))
  58.            Console.WriteLine()
  59.        Else
  60.  
  61.  
  62.            Console.WriteLine(String.Format("{0,-16}   {1,-16}   {2,-16}   {3}",
  63.                                            (stops - 1).ToString("00"),
  64.                                            goOut.ToString("00"),
  65.                                            goIn.ToString("00"),
  66.                                            passengers.ToString("00")))
  67.        End If
  68.  
  69. #End If
  70.  
  71.        Select Case stops
  72.  
  73.            Case 1 ' Out:5, In:2, Current:47.
  74.                goOut = 5
  75.                goIn = 2
  76.  
  77.            Case 2 ' Out:3, In:4, Current:48.
  78.                goOut = 3
  79.                goIn = 4
  80.  
  81.            Case 3 ' Out:10, In:5, Current:43.
  82.                goOut = 10
  83.                goIn = 5
  84.  
  85.            Case 4 ' Out:8, In:5, Current:40.
  86.                goOut = 8
  87.                goIn = 5
  88.  
  89.            Case 5 ' Out:2, In:2, Current:40.
  90.                goOut = 2
  91.                goIn = 2
  92.  
  93.            Case Else
  94.                Return New KeyValuePair(Of Integer, Integer)(goOutTotal, goInTotal)
  95.  
  96.        End Select
  97.  
  98.        ' Total amount of passengers that remains inside the bus.
  99.        passengers = (passengers - goOut + goIn)
  100.  
  101.        BusPassengers = BusPassengers(passengers)
  102.  
  103.    End Function
  104.  
  105. End Module

C#:
En C#, al ser un lenguaje con la desventaja de no poder usar el keyword Static dentro de métodos para declarar variables estáticas cuyo valor modificado perdura en las siguientes llamadas al método, me ha costado un poquito la traducción manual de VB.Net C#, queda un poco feo por las variables pasadas por referencia goOutTotal y goInTotal y las demás, pero paso de complicarlo más o buscar la manera de simplificarlo, funciona, que es lo importante, aquí tienes:

Código
  1. using System.Collections.Generic;
  2. using System.Collections;
  3. using System.Data;
  4. using System.Diagnostics;
  5. using System.Linq;
  6. using System.Text;
  7. using System;
  8.  
  9. namespace ConsoleApplication2
  10. {
  11.    class Program
  12.    {
  13.  
  14.        static void Main(string[] args)
  15.        {
  16.            int currentPassengers = 50;
  17.            int goOutTotal = 0;
  18.            int goInTotal = 0;
  19.            KeyValuePair<int, int> result = BusPassengers(ref currentPassengers, ref goOutTotal, ref goInTotal);
  20.  
  21.            Console.WriteLine();
  22.            Console.WriteLine(string.Format("Current Pas.: {0,2}, Pas. that left out: {1,2} | Pas. that entered into: {2,2}",
  23.                                            currentPassengers.ToString("00"), result.Key.ToString("00"), result.Value.ToString("00")));
  24.            Console.ReadKey();
  25.        }
  26.  
  27.        /// ----------------------------------------------------------------------------------------------------
  28.        /// <summary>
  29.        /// </summary>
  30.        /// ----------------------------------------------------------------------------------------------------
  31.        /// <param name="passengers">
  32.        /// The current amount of passengers that are inside the bus.
  33.        /// </param>
  34.        /// ----------------------------------------------------------------------------------------------------
  35.        /// <returns>
  36.        /// An <see cref="KeyValuePair"/> instance where the
  37.        /// <see cref="KeyValuePair.Key"/> property contains the total amount of passengers that left out the bus, and the
  38.        /// <see cref="KeyValuePair.Value"/> property contains the total amount of passengers that entered into the bus.
  39.        /// </returns>
  40.        /// ----------------------------------------------------------------------------------------------------
  41.        private static KeyValuePair<int, int> BusPassengers(ref int passengers,
  42.                                                            ref int goOutTotal,
  43.                                                            ref int goInTotal,
  44.                                                            int stops = 0,
  45.                                                            int goOut = 0,
  46.                                                            int goIn = 0)
  47.        {
  48.  
  49.            stops += 1; // Bus-Stop count.
  50.            goOutTotal += goOut; // Total amount of passengers that left out the bus.
  51.            goInTotal += goIn; // Total amount of passengers that entered into the bus.
  52.  
  53. #if DEBUG
  54.    if (stops > 1)
  55.    {
  56.        Console.WriteLine(string.Format("Stop: {0} | Pas. out: {1,2} | Pas. In: {2,2} | Total pas.: {3}",
  57.                                        (stops - 1).ToString("00"), goOut.ToString("00"), goIn.ToString("00"), passengers.ToString("00")));
  58.    }
  59. #endif
  60.  
  61.            switch (stops)
  62.            {
  63.                case 1: // Out:5, In:2, Current:47.
  64.                    goOut = 5;
  65.                    goIn = 2;
  66.                    break;
  67.  
  68.                case 2: // Out:3, In:4, Current:48.
  69.                    goOut = 3;
  70.                    goIn = 4;
  71.                    break;
  72.  
  73.                case 3: // Out:10, In:5, Current:43.
  74.                    goOut = 10;
  75.                    goIn = 5;
  76.                    break;
  77.  
  78.                case 4: // Out:8, In:5, Current:40.
  79.                    goOut = 8;
  80.                    goIn = 5;
  81.                    break;
  82.  
  83.                case 5: // Out:2, In:2, Current:40.
  84.                    goOut = 2;
  85.                    goIn = 2;
  86.                    break;
  87.  
  88.                default:
  89.                    return new KeyValuePair<int, int>(goOutTotal, goInTotal);
  90.            }
  91.  
  92.            passengers = (passengers - goOut + goIn);
  93.            return BusPassengers(ref passengers, ref goOutTotal, ref goInTotal, stop, goOut, goIn);
  94.  
  95.        }
  96.  
  97.    }
  98. }

Resultado de ejecución (versión VB.Net):



Saludos.


« Última modificación: 13 Septiembre 2015, 20:08 pm por Eleкtro » En línea


40

Desconectado Desconectado

Mensajes: 2


Ver Perfil
Re: Ayuda con Recursividad
« Respuesta #2 en: 14 Septiembre 2015, 04:15 am »

En serio muchas muchas gracias!!!  ;-)
Gracias por todo y yo también pienso que esto tampoco lo aplicaré en la vida real, pero ni modo lo que diga el profe  :P
En línea

DarK_FirefoX


Desconectado Desconectado

Mensajes: 1.250


Be the change you wanna see in te world


Ver Perfil
Re: Ayuda con Recursividad
« Respuesta #3 en: 14 Septiembre 2015, 18:19 pm »

El problema precisamente es la recursividad, no se en que página web o que profesor te ha mandado el ejercicio, pero es una metodología que se debe evitar sin excepción alguna, a menos que simplemente sea para aprender el concepto de recursividad y ya está (aunque en mi humilde opinión de nada sirve aprender eso).

En verdad puede que tengas razón en cierta manera, pues quizás para este problema no sea necesario la recursividad para resolverlo, pero si que pienso yo que se debe aprender a pensar recursivamente.

Existen muchas cosas que se utilizan mucho que tienen implementaciones recursivas mucho más sencillas que iterativas.

Por ejemplo:

La implementación de árboles, si bien se puede hacer iterativamente, requeriría muchas lineas de código y un seguimiento del flujo del programa muy muy intenso para realizar operaciones que se expresan sencillamente utilizando la recursividad. Ejemplo de esto son las Estructuras de Datos: Árbol binario de busqueda (BST), HEAPS, AVL, RB Tree, B Tree, entre otras coas como algoritmos que trabajen sobre Grafos (BFS, DFS, PRIM, Kruskal, Bellman-Ford, Algoritmos para resolver problemas de flujo máximo).

Ah, el más sencillo ejemplo del poder de la recursividad es la solución del problema de las Torres de Hanoi. Hacerlo iterativamente es bastante tedioso

En fin, en mi opinión si bien no es recomendable usarlo para todo, un buen diseñado algoritmo recursivo es tán útil como un algoritmo iterativo.

C#:
En C#, al ser un lenguaje con la desventaja de no poder usar el keyword Static dentro de métodos para declarar variables estáticas cuyo valor modificado perdura en las siguientes llamadas al método, me ha costado un poquito la traducción manual de VB.Net C#, queda un poco feo por las variables pasadas por referencia goOutTotal y goInTotal y las demás, pero paso de complicarlo más o buscar la manera de simplificarlo, funciona, que es lo importante, aquí tienes:

No lo puedes declarar dentro del método, pero si lo puedes declarar en el ámbito del método, en este caso en la clase Program y perdurará en las llamadas recursivas del método, así eliminas el uso de las variables por referencia.

Salu2s
« Última modificación: 14 Septiembre 2015, 18:21 pm por DarK_FirefoX » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
ayuda con recursividad
.NET (C#, VB.NET, ASP)
eagle17 2 2,281 Último mensaje 1 Marzo 2009, 10:29 am
por bitarray
ayuda recursividad
.NET (C#, VB.NET, ASP)
Choclito 2 1,832 Último mensaje 14 Mayo 2009, 03:38 am
por Choclito
Ayuda recursividad « 1 2 »
Programación C/C++
JUHC 10 6,185 Último mensaje 8 Agosto 2016, 16:41 pm
por AlbertoBSD
AYUDA CON RECURSIVIDAD « 1 2 »
Programación C/C++
alpachino98 11 2,677 Último mensaje 7 Febrero 2018, 15:08 pm
por dijsktra
ayuda con recursividad en java
Ejercicios
manzur soria 1 1,117 Último mensaje 18 Marzo 2018, 22:59 pm
por MCKSys Argentina
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines