[C] Recursividad

zildjian

Hola MVeros, mañana tengo examen de programación 2 y hay algo que aún no me ha quedado muy claro, que es la recursividad. O sea, el concepto lo tengo claro pero hay un ejercicio de un examen que no sabría cómo hacerlo, y es el siguiente, a ver si me podéis echar un cable:

Escribe una función recursiva que mire si los elementos de un vector estén en orden estrictamente creciente y que retorne 1 en cuanto esté ordenado y 0 en cualquier otro caso.

Seguro que para muchos de vosotros esto es una parida pero... :(

Saludos!

GODSWIND

pero eso no se hace con un bucle? mañana tienes el examen?

cabron

Una función recursiva es una función que se llama así misma, así de simple.

Dentro de la función, antes de llamarse así misma, se debe comprobar alguna condición, de lo contrario se llamaría así misma hasta el infinito (bueno, hasta saturar la pila con las llamadas más bien).

Sobre lo que te piden, pues de manera recursiva, podrías tener hacer una función que compruebe si un elemento es mayor que otro. La función la llamas desde fuera para que compruebe el primer y segundo elemento, después la función se llama así misma con el segundo y tercer elemento, luego se llama así misma con el tercero y el cuarto, etc, hasta que no haya más elementos. Si llega hasta al final sin encontrar ningún fallo en la ordenación devuelve 1, en el momento en el que encuentre una pareja de elmentos que no estén ordenados, devuelve 0 (esa sería la condición que usarias para decidir si la función se vuelve a llamar a sí misma)

#2:

Todo lo que es recursivo, se puede implementar con un bucle, si le han pedido que lo haga de forma recursiva sin usar un bucle, será para comprobar que entiende como funciona la recursividad.

zildjian

Hasta ahí llego, perdón por haberme expresado mal. Mi pregunta exacta es: ¿cuándo tiene que parar? Porque el vector no tiene longitud infinita... aunque supongo que a la función también se le podría pasar por parámetro la medida del vector, pero eso ya no es tan "elegante"... xD

cabron

En C siempre tienes que enviar la longitud de un vector , ya que no existe ninguna forma de conocerla (lo más parecido sería sizeof(miVector) /sizeof(tipoDelVector) siempre que tengas el vector en sí, y no un puntero)

Tienes que parar en cuanto no haya más elementos para comprobar, o en cuanto encuentros dos que no están ordenados.

Kartalon

Yo lo haría con dos if, primero uno que compruebe que no desbordas el vector (y evitar que la recursividad se vaya de bareta) y dentro otro if que compare el valor actual de la posición en la que nos encontramos AND llamamos a la función y la comparamos para que sea 1, en tal caso devolvemos 1, en otro caso devolvemos 0.

Así a ojo, lo haría, pero estoy tope vago y acabé los exámenes ayer.

El prototipo de la función, así a botepronto, sería:
int creciente(int *vector, int tam_vector, int posicion);

(Quizás me equivoque, como he dicho no lo he probado y ando de resaca, amén que es lo primero que se me ha ocurrido.)

zildjian

Vale, creo que ya está hecho aunque obviamente NO es lo más óptimo, pero vamos, lo he hecho pasito por pasito en papel y lápiz y parece (xD) que funciona:

int ord_recur(int *v, int tam){
    while(i != tam){
        if(v[i+1] > v[i]){
            continue;
        }else{
            swap(v[i+1], v[i]);
            ord_recur(v, tam);
        }
        
i++; } return 1; }

Estaría esto aceptable? O no va así la cosa? XD Lo digo porque si no, me podríais decir en qué me he equivocado o algo :f5:

cabron

Sin mirar si funciona o no, te puedo decir que eso no es lo que pide el ejercicio..., según leo yo, solo te pide que compruebe si está ordenado o no, no que lo ordene...

LOc0

Todo lo que te han dicho es correcto. Como dices que tienes el examen hoy y para que no te quedes con la duda, por si acaso te pongo una posible solución:

spoiler

¡Suerte!

Salu2 ;)

PiradoIV

Acordaros del comando [code][/code] para estos casos.

zildjian

Muchas gracias, al final me ha ido bien y todo el examen! :D

1 comentario moderado
erdanblo

#12 http://www.mediavida.com/foro/8/spoilersois-unos-cansinosspoiler-364505

LOc0

#10

Pues pasé del

 porque no me gustaba mucho el de MV5 (por lo de que te metía los números de línea), pero veo que lo han cambiado y a mi gusto a mejor.

Salu2 ;)
RoDRa

todo lo que te han dicho en el hilo esta bien y ademas parece que la duda esta resuelta, lo que me extraña es que nadie explique las reglas de toda funcion recursiva, las voy a poner por si alguien entra en el hilo con la misma duda, puede que le sirva. A mi me ayudo bastante en su dia

Recursividad en programacion es una funcion que se llama a si misma (hasta aqui creo que es evidente xD)

caso base - En toda funcion recursiva debe haber un caso base (o mas), que suele ser un caso trivial al llamar a la funcion (en tu caso seria un vector vacio o el final del vector)

progreso - Cuando se llama a la funcion dentro de la propia funcion recursiva se le debe dar un caso que se acerque al más al caso base (con el vector seria que compruebe la siguiente a partir de la siguiente posicion). De otra forma nunca acabariamos llegando al caso base

diseño - se debe suponer que las llamadas recursivas funcionaran

interes compuesto - no duplicar nunca el problema

y aqui el tipico ejemplo de funcion recursiva de toda la vida, el factorial de un numero

int FactorialR(int IntNumero)
{
if (IntNumero==1) //caso base
return(1);
else
return(IntNumero * FactorialR(IntNumero-1)); //llamada recursiva y progreso
}

en el caso base vemos el caso trivial de factorial de 1 (que es 1) y en el progreso se ve que se llama a factorial de un numero menor (que se supone que se acerca a 1 en casi todos los casos, a no ser que llamemos la funcion con un numero menor a 1 que crearia un bucle infinito)

espero que le sirva a alguien

JuAn4k4

#15 mec! El caso base/trivial es : Cuando el vector esta vacio y cuando solo hay 1 elemento , en ambos casos se retorna 1.

La cosa es encontrar el caso trivial, y llegar a el reduciendo el problema ( en este caso el vector ) hasta llegar a el.

Esta ordenado si estan ordenados los 2 primeros y el resto.

El resto es la llamada recursiva con 1 elemento menos.

Asi hasta llegar al ultimo elemento, donde dices que si esta ordenado, tambien puedes parar cuando quedan 2.

Y si el vector esta vacio tb es ta ordenado.

Josekron

Para comprender mejor la recursividad, empieza siempre por definir el caso base.

"Escribe una función recursiva que mire si los elementos de un vector estén en orden estrictamente creciente y que retorne 1 en cuanto esté ordenado y 0 en cualquier otro caso."

El caso base es el caso que sabes que siempre se cumple. En este ejercicio, ¿cuándo terminaría la función? Terminaría cuando hubiera recorrido todo el vector[j] ( j > MAXVECTOR), es decir, si ha recorrido todo el vector quiere decir que ha verificado que todas las posiciones están ordenadas.

Puede existir más de un caso base
, como es el caso. ¿Qué tiene que ocurrir para que el resultado sea 0? Que el valor de la actual posición del vector sea menor que el valor de la anterior posición (ya no sería creciente).

Si (j>MAXVECTOR) entonces
Resultado = 1
SinoSi (vector[j]<num) entonces
Resultado = 0
EnOtroCaso
...
...
FinSi

Una vez sacado los casos base, lo demás sale casi automáticamente.

FUNC VectorCreciente (v :vector; j: natural, num: natural): natural
INICIO
Si (i>MAXVECTOR) entonces
Resultado = 1
SinoSi (vector[j]<num) entonces
Resultado = 0
EnOtroCaso
Resultado = VectorCreciente (v,j+1, v[j])
FinSi
FIN

Usuarios habituales

  • RoDRa
  • LOc0
  • erdanblo
  • zildjian
  • PiradoIV
  • cabron
  • GODSWIND