Sei sulla pagina 1di 9

Prctica 9

Funciones Recursivas

Directorio de la Prctica
Cree el subdirectorio precursiva en su directorio de inicio de sesin y sitese en l.
Escriba todos los programas de esta prctica en dicho directorio.
Descarge en dicho directorio el archivo comprimido recursiva.zip y descomprmalo.
Paso de Tablas Bidimensionales como Parmetro
En este ejercicio se practicarn los diferentes mtodos para pasar una tabla multidimensional como parmetro a una funcin. Repase lo relacionado con tablas multidimesionales en el apartado 9.8 de los apuntes de la asignatura, donde podr ver algunos ejemplos
directamente aplicables a esta prctica. En todos los casos deber implementar la funcin
imprimeTabla, dependiendo de cmo se declare dicha funcin.
Ejercicio1
a) En este primer caso se pasan tres parmetros a la funcin: una tabla multimensional
de la que no es necesario especificar su dimensin ms interna (y slo esa) y las
dos dimensiones de la tabla.


/*
Fichero:
**
Autor:
**
Fecha:
**
**
** Descripcion:
**
*/

tablasMultidim1.c
Departamento de Ingeniera Telemtica
5-diciembre-2014
Implementa una funcin que imprime una tabla bidimensional
que se le pasa como parmetro.

/* Includes del sistema */


#include <stdio.h>

/* Includes de la aplicacion */

289

290

Captulo 9. Funciones Recursivas


/* Definicin de constantes */
#define TAMV 6
#define TAMH 4

/* Tipos definidos por el usuario */


/* Declaracin de funciones locales. */
/*
Parmetros: tabla
tabla bidimensional que se desea imprimir.
**
En este caso el parmetro es del tipo tabla
**
bidimensional.
**
tamh
nmero de columnas de la tabla bidimensional.
**
tamv
nmero de filas de la tabla bidimensional.
**
**
Devuelve: Nada
**
**
** Descripcion: Muestra los elementos de una tabla bidimensional que se
proporciona como parmetro.
**
Los elementos se muestran por filas
**
mediante el uso de un doble bucle.
**
*/
void imprimeTabla(char tabla[][TAMH], int tamh, int tamv);

/************************************************************/
int main ()
{
char tabla [
{A, B,
{E, F,
{I, J,
{M, N,
{Q, R,
{U, V,
};

TAMV
C,
G,
K,
O,
S,
W,

][ TAMH ] = {
D},
H},
L},
P},
T},
X}

imprimeTabla(tabla, TAMV, TAMH);


return 0;
}
void imprimeTabla(char tabla[][TAMH], int tamv, int tamh)
{

Compile y ejecute el programa tal y como lo ha hecho en las prcticas anteriores.


Hgalo tambin utilizando el makefile proporcionado tecleando:
make -f multidimensionales tablasMultidim1
b) En este caso, tambin se pasan tres parmetros a la funcin: una tabla en la que
cada elemento es una tabla y las dimensiones de las dos tablas.


/*
Fichero:
**
Autor:
**
Fecha:
**
**
** Descripcion:
**

tablasMultidim2.c
Departamento de Ingeniera Telemtica
5-diciembre-2014
Implementa una funcin que imprime una tabla bidimensional
que se le pasa como parmetro.

291

*/
/* Includes del sistema */
#include <stdio.h>

/* Includes de la aplicacion */
/* Definicin de constantes */
#define TAMV 6
#define TAMH 4

/* Tipos definidos por el usuario */


/* Declaracin de funciones locales. */
/*
Parmetros: tabla
tabla bidimensional que se desea imprimir.
**
En este caso el parmetro es del tipo tabla
**
de tablas.
**
tamh
nmero de columnas de la tabla bidimensional.
**
tamv
nmero de filas de la tabla bidimensional.
**
**
Devuelve: Nada
**
**
Descripcion:
Muestra los elementos de una tabla bidimensional que se
**
proporciona como parmetro.
**
Los elementos se muestran por filas
**
mediante el uso de un doble bucle.
**
*/
void imprimeTabla(char (*tabla)[TAMH], int tamh, int tamv);
/************************************************************/
int main ()
{
char tabla [
{A, B,
{E, F,
{I, J,
{M, N,
{Q, R,
{U, V,
};

TAMV
C,
G,
K,
O,
S,
W,

][ TAMH ] = {
D},
H},
L},
P},
T},
X}

imprimeTabla(tabla, TAMV, TAMH);


return 0;
}
void imprimeTabla( char (*tabla)[TAMH], int tamv, int tamh)
{

Compile y ejecute el programa tal y como lo ha hecho en las prcticas anteriores.


Hgalo tambin utilizando el makefile proporcionado tecleando:
make -f multidimensionales tablasMultidim2

292

Captulo 9. Funciones Recursivas


c) En este ejemplo, el parmetro que se pasa es la direccin de comienzo de una tabla
unidimensional. Se est utilizando el hecho de que los elementos de cualquier tabla
(uni o multidimensional) son consecutivos en memoria.


/*
Fichero:
**
Autor:
**
Fecha:
**
**
** Descripcion:
**
*/

tablasMultidim3.c
Departamento de Ingeniera Telemtica
5-diciembre-2014
Implementa una funcin que imprime una tabla bidimensional
que se le pasa como parmetro.

/* Includes del sistema */


#include <stdio.h>

/* Includes de la aplicacion */
/* Definicin de constantes */
#define TAMV 6
#define TAMH 4

/* Tipos definidos por el usuario */


/* Declaracin de funciones locales. */
/*
Parmetros: tabla
tabla bidimensional que se desea imprimir.
**
En este caso el parmetro es del tipo tabla,
**
aprovechando que los elementos de una tabla
**
multidimensional son todos consecutivos,
**
como los de una tabla unidimensional.
**
tamh
nmero de columnas de la tabla bidimensional.
**
tamv
nmero de filas de la tabla bidimensional.
**
**
Devuelve: Nada
**
**
** Descripcion: Muestra los elementos de una tabla bidimensional que se
proporciona como parmetro.
**
Los elementos se muestran por filas
**
mediante el uso de un doble bucle.
**
*/
void imprimeTabla(char *tabla, int tamh, int tamv);
/************************************************************/
int main ()
{
char tabla [
{A, B,
{E, F,
{I, J,
{M, N,
{Q, R,
{U, V,
};

TAMV
C,
G,
K,
O,
S,
W,

][ TAMH ] = {
D},
H},
L},
P},
T},
X}

imprimeTabla(tabla[0], TAMH, TAMV);


printf("\n");
imprimeTabla(&tabla[0][0], TAMV, TAMH);

293

return 0;
}
void imprimeTabla( char *tabla, int tamv, int tamh)
{

En este caso, la obtencin del elemento correspondiente a una fila y una columna
deber hacerla la implementacin de la funcin, sabiendo que el tercer elemento
de la primera fila sera el de ndice 2 (recuerde que en C el primer elemento de
cualquier tabla es el de ndice cero), el cuarto elemento de la segunda fila sera
TAMH + 3, ... y, en general, el m elemento de la fila n sera:
(n 1) TAMH + m 1
Repase el primer mtodo del apartado 11.2.4 de los apuntes.
Compile y ejecute el programa tal y como lo ha hecho en las prcticas anteriores.
Hgalo tambin utilizando el makefile proporcionado tecleando:
make -f multidimensionales tablasMultidim3
Resolucin de un laberinto
Se pretende encontrar de forma recursiva un camino de salida en un laberinto.
Vamos a suponer que el laberinto es un recinto rectangular dividido en cuadrados,
estando cada cuadro o bien ocupado por un obstculo (se representa con el carcter #) o
bien libre (carcter .). El permetro del rectngulo est ocupado por obstculos, excepto
en una o ms salidas. Se pretende buscar slamente una salida, aunque pueden existir
varias o ninguna.
La siguiente figura recoge un ejemplo de laberinto:
#
#
#
#
#
#
#
#

#
.
#
.
#
.
.
#

#
.
.
.
#
.
#
#

#
#
.
#
.
.
.
#

#
#
.
.
.
#
.
#

#
#
#
#
.
#
.
#

#
.
.
.
.
#
.
#

#
.
#
#
#
.
.
#

#
.
#
.
#
.
#
#

#
.
#
.
#
.
#
#

#
#
.
.
#
.
.
.

#
#
#
#
#
#
#
#

Comenzamos en alguna posicin (columna , fila) dentro del laberinto que no sea
un obstculo, (es decir, no se puede comenzar en una posicin que contenga el carcter
#), y tenemos que encontrar un camino hasta una de las salidas. Desde una posicin del
laberinto, podemos movernos a las casillas situadas a la derecha, a la izquierda, abajo
o arriba (nunca en diagonal), pero siempre que dicha casilla no est ocupada por un
obstculo.
Se ha encontrado una ruta cuando se llega a una posicin sin obstculo en los lmites
del laberinto.

294

Captulo 9. Funciones Recursivas


Si marcamos cada casilla recorrida con un crculo (o) y cada casilla que forma parte
de la solucin con un asterisco (*), la representacin de la solucin del laberinto anterior
partiendo de la casilla (1,1) ser:
#
#
#
#
#
#
#
#

#
*
#
.
#
o
o
#

#
*
*
.
#
o
#
#

#
#
*
#
*
*
*
#

#
#
*
*
*
#
*
#

#
#
#
#
o
#
*
#

#
o
o
o
o
#
*
#

#
o
#
#
#
*
*
#

#
o
#
.
#
*
#
#

#
o
#
.
#
*
#
#

#
#
.
.
#
*
*
*

#
#
#
#
#
#
#
#

A partir de un determinado punto de comienzo, puede ser que no exista ruta de salida.
En el laberinto anterior, si el punto de comienzo es el (10, 2) no existe ruta de salida.
Ejercicio 2
Realizar un programa que permita obtener la solucin a un laberinto mediante una funcin recursiva de nombre encuentraRuta. A continuacin se proporciona el diagrama de flujo de una posible solucin a dicha funcin:

295

Representaremos el laberinto mediante una matriz bidimensional de tipo char y de


nombre laberinto. La anchura (TAMH), la altura (TAMV) y el diseo del laberinto
(LABERINTO) sern constantes definidas en un archivo de cabecera laberinto.h,
que se incluir en los ficheros fuente.
Con estas premisas, la definicin del laberinto en el fichero fuente se har mediante la
siguiente sentencia:
char laberinto[TAMV][TAMH] = {LABERINTO};
Esto permitir experimentar con distintos laberintos modificando nicamente este archivo y recompilando los programas.
La asignacin:
laberinto[y][x] = o;
marca cada posicin del laberinto cuando se visita; esto es fundamental para asegurar
que no se dan vueltas en crculos, mientras que la asignacin:
laberinto[y][x] = *;
marca cada posicin que est en el camino desde el punto indicado como comienzo hasta
la salida.
Se pide:
Implementar en lenguaje C la funcin recursiva encuentraRuta, definida en el
archivo encruta1.c y declarada en el correspondiente encruta1.h, a la que
se le pasa inicialmente la posicin de comienzo (nmero de columna y nmero
de fila), y el propio laberinto (la matriz que contiene la definicin), y que deber
buscar el camino en el siguiente orden: hacia la derecha, hacia la izquierda, hacia
abajo y por ltimo hacia arriba. La funcin devuelve un entero, que valdr 1 si se
ha encontrado la salida, y 0 en caso contrario.
Escriba en otro fichero (laberinto1.c) la funcin principal que reciba como
argumentos las coordenadas del punto de comienzo (primero la columna y luego
la fila) y que:
compruebe que el nmero de parmetros es el adecuado.
compruebe que el punto indicado cae dentro del laberinto.
compruebe que el punto indicado no es un obstculo.
haga uso de la funcin encuentraRuta para buscar la solucin.
imprima el resultado de la bsqueda.
Realice el fichero Makefile que permita realizar la compilacin separada.
Al escribir la solucin hayada por pantalla no deben existir lineas vacas (retornos de
carro) antes o despus de la misma. Tampoco deben existir caracteres en blanco a la
izquierda o derecha de la solucin.
El siguiente es un ejemplo de ejecucin del programa dado el siguiente laberinto:
############
#..###....##
##...#.###.#

296

Captulo 9. Funciones Recursivas


#..#.#.#...#
###....#####
#...###....#
#.#.....##.#
##########.#



salas@318CDCr12:$ ./laberinto1
Numero incorrecto de parametros.
salas@318CDCr12:$ ./laberinto1 1 2 3
Numero incorrecto de parametros.
salas@318CDCr12:$ ./laberinto1 12 15
El punto (12, 15) no pertenece al laberinto.
salas@318CDCr12:$ ./laberinto1 2 4
El punto (2, 4) es un obstaculo.
salas@318CDCr12:$ ./laberinto1 10 2
No existe salida desde el punto (10, 2).
salas@318CDCr12:$ ./laberinto1 2 1
############
#o*###oooo##
##***#o###.#
#..#*#o#...#
###**oo#####
#oo*###****#
#o#*****##*#
##########*#
salas@318CDCr12:$

Ejercicio 3
Realice una modificacin del programa anterior (laberinto2.c) para que la solucin
presentada por pantalla slo recoja la solucin final, y no los diferentes intentos que han
sido necesarios hasta llegar a dicha solucin.
Modifique tambin el archivo Makefile para que la compilacin de esta segunda versin tambin se realice por defecto (regla todo), es decir, al invocar al comando make deben compilarse automaticamente laberinto1 y laberinto2. Tambin
incluya en el archivo Makefile, una regla borra que elimine los dos ejecutables
(laberinto1 y laberinto2) as como todos los archivos objeto.
El siguiente es un ejemplo de ejecucin del programa dado el siguiente laberinto:
############
#..###....##
##...#.###.#
#..#.#.#...#
###....#####
#...###....#
#.#.....##.#
##########.#

297


salas@318CDCr12:$ ./laberinto2
Numero incorrecto de parametros.
salas@318CDCr12:$ ./laberinto2 1 2 3
Numero incorrecto de parametros.
salas@318CDCr12:$ ./laberinto2 12 15
El punto (12, 15) no pertenece al laberinto.
salas@318CDCr12:$ ./laberinto2 2 4
El punto (2, 4) es un obstaculo.
salas@318CDCr12:$ ./laberinto2 10 2
No existe salida desde el punto (10, 2).
salas@318CDCr12:$ ./laberinto2 2 1
############
#.*###....##
##***#.###.#
#..#*#.#...#
###**..#####
#..*###****#
#.#*****##*#
##########*#
salas@318CDCr12:$

Entrega
Deber entregar un fichero practica09.zip que contenga un nico directorio precursiva
en el que se ubiquen los siguientes ficheros fuente (y slo stos):
multidim1.c
multidim2.c
multidim3.c
Makefile
encruta1.h
encruta1.c
laberinto1.c (cdigo fuente) y laberinto1.dia (diagrama de flujo).
laberinto2.c (cdigo fuente) y laberinto2.dia (diagrama de flujo).

Potrebbero piacerti anche