Document

Anuncio
Soluciones a los ejercicios planteados en
el curso
Unidad 3 - Algoritmos recursivos
Lección 2 – Mecanismo de recursividad
1
Escribe un algoritmo recursivo que calcule el elemento de
cardinal más elevado de un vector de datos de tipo
entero.
Por ejemplo, para la entrada {1, 3, 25, 9, 20} obtendremos
como resultado 25.
Para simplificar el algoritmo, pasaremos como parámetros el índice actual
dentro del vector de números así como el número de cardinal más elevado hasta el
momento max.
El caso base o condición de salida es la llegada al fin del vector, en cuyo
caso devolvemos simplemente el valor max obtenido hasta el momento. En el resto
de casos, se compara el elemento en la posición actual del vector con max y se
actualiza el valor de max si corresponde. En todo caso, se llama de nuevo a la
función recursiva incrementando la posición dentro del vector de números:
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int numeros[] = {1, 5, 25, 20, 2};
int NUMS = 5;
int mayor(int indice, int max)
{
if(indice == NUMS - 1)
{
return max;
}
else
{
if( numeros[indice] > max )
max = numeros[indice];
return mayor( indice + 1, max);
}
}
[Haz clic aquí y escribe el título de la unidad didáctica]
1
int main()
{
int resultado = mayor(0, -1);
printf("Resultado: %d", resultado);
return 0;
}
___________________________________________________________
2
n
El valor de x se puede definir recursivamente como:
x0 = 1
xn = x * xn – 1
Implementa de forma recursivo el cálculo de x
cualquier valor de X y n.
n
para
La función recursiva recibirá dos parámetros: la base (X) y el exponente (n)
0
al que se eleva la base. En este caso, el caso base lo constituye el caso x = 1. En
el resto de casos, llamamos a la función recursiva multiplicando, tal y como indica
la fórmula, la base por ella misma elevada al exponente decrementado en una
unidad.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int potencia(int base, int exponente)
{
if(exponente == 0)
{
return 1;
}
else
{
return base * potencia(base, exponente - 1);
}
}
int main()
{
int resultado = potencia(3, 5);
printf("Resultado: %d", resultado);
return 0;
}
___________________________________________________________
Lección 5 – Recursividad vs. Iteración
[Haz clic aquí y escribe el título de la unidad didáctica]
2
1
Reescribe el algoritmo para calcular el factorial de un
número de forma iterativa.
Para implementar iterativamente el algoritmo basta con preparar un bucle
que multiplique el número con todos los números inferiores a él hasta llegar a 1.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int factorial(int num)
{
int resultado = num;
int i;
for(i = num - 1;i > 0; i--)
{
resultado *= i;
}
return resultado;
}
int main()
{
printf("El factorial del número 7 es %d\n", factorial(7));
return 0;
}
___________________________________________________________
Unidad 4 - Algoritmos de búsqueda
Lección 2 – Búsqueda secuencial
1
Reescribe la función busquedaSecuencial para que
devuelva, en lugar de Verdadero, la posición del dato
buscado si éste se localiza. ¿Qué valor podemos devolver
para indicar que no se encontró el valor buscado?
Recordemos que para comprobar cuando ha llegado al final del vector, el
algoritmo mantiene en la variable pos la posición actual dentro del mismo. De modo
[Haz clic aquí y escribe el título de la unidad didáctica]
3
que simplemente sustituyendo Verdadero por pos podremos devolver la posición en
la que se ha encontrado el elemento.
No tan trivial resulta la elección del valor a devolver si no se encuentra el
dato buscado. Ya no es posible devolver Falso* puesto que es un valor booleano y
el tipo de dato devuelto ahora es entero (pos es un valor entero). Podríamos elegir
el valor 0 pero es necesario recordar que en la mayoría de lenguajes el primer
elemento de un vector se representa con el índice 0, de modo que ¿qué pasaría si
el valor buscado se encontrase en la primera posición, de índice 0? La solución
idónea puede ser devolver el valor -1, que es de tipo entero. Los elementos del
vector siempre son números enteros positivos lo cual elimina cualquier posible
ambigüedad al respecto:
Algoritmo en pseudocódigo______________________________________
funcion busquedaSecuencial (vector, dato)
pos := 0
tam := tamaño(vector)
mientras pos < tam
si (vector[pos] = dato) entonces
devolver pos
fin si
pos = pos + 1
fin mientras
devolver -1
fin funcion
___________________________________________________________
* En realidad generalmente es posible ya que en muchos lenguajes Falso se
convertirá al valor 0 (entero) si es necesario. Pero aquí buscamos un algoritmo
teóricamente correcto.
Lección 3 – Búsqueda binaria
1
Reescribe el algoritmo de búsqueda binaria de forma
recursiva.
Algoritmo en pseudocódigo______________________________________
funcion busquedaBinaria(vector, izq, der, dato)
centro := (izq + der) / 2
si izq > der entonces
devolver -1
sino si (vector[centro] = dato) entonces
devolver centro
sino si (dato < vector[centro]) entonces
[Haz clic aquí y escribe el título de la unidad didáctica]
4
sino
fin si
fin funcion
devolver busquedaBinaria(vector, izq, centro - 1, dato)
devolver busquedaBinaria(vector, centro + 1, der, dato)
La llamada inicial a la función será la siguiente:
busquedaBinaria(vector, 0, tamaño(vector) – 1, dato)
___________________________________________________________
Unidad 5 - Algoritmos de ordenación
Midiendo la eficiencia de los algoritmos
Para medir la eficiencia de estos algoritmos y poder compararlos entre sí, o
comparar la eficiencia para distintos tipos de entrada (vectores ordenados, no
ordenados, casi ordenados…) podemos utilizar la función clock incluída en time.h.
clock() devuelve los ‘ticks’ transcurridos desde el inicio del programa, en
milisegundos. Si haces una llamada a clock() justo antes de llamar al algoritmo de
ordenación y otra llamada justo después, podrás obtener el tiempo de ejecución del
algoritmo restando al valor obtenido en la segunda llamada el obtenido en la
primera:
#include <time.h>
…
long tiempo = clock();
ordena();
tiempo = clock() – tiempo;
printf(“El tiempo en milisegundos es %ld”, tiempo);
…
Ten en cuenta que para vectores de entrada pequeños y/o ordenadores
rápidos (cualquiera de hoy en día) el tiempo devuelto puede ser 0 milisegundos, lo
cual sirve de poca ayuda. Prueba a trabajar con vectores de entrada más grandes.
Mostrando el vector en pantalla
Puedes utilizar esta función para mostrar en pantalla un vector de tipo int.
Te será útil para observar el estado del vector antes y después de ser ordenado:
void imprimeContenidoVector()
{
int i;
printf("El vector antes de ser ordenado\n");
printf("{");
for(i = 0;i < tamanoVector; i++ )
{
printf("%d", vector[i]);
if( i < tamanoVector - 1)
{
[Haz clic aquí y escribe el título de la unidad didáctica]
5
}
printf(", ");
}
printf("}\n");
}
Ten en cuenta que hace uso de las variables globales vector y tamanoVector
que deberán existir y estar convenientemente inicializadas.
Con objeto de simplificar el código trabajaremos con
variables globales para representar el vector de datos a
ordenar.
Lección 2 – Inserción directa
1
Implementa el algoritmo de inserción directa en un lenguaje
de tu elección y pruébalo con distintas entradas. Comprueba
su eficiencia con vectores ordenados, casi ordenados y no
ordenados.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int vector[] = {10, 99, 35, 25, 3, 7, 80, 22, 45, 23};
int tamanoVector = 10;
void ordenaInsercionDirecta()
{
int indice;
for(indice = 0; indice < tamanoVector; indice++)
{
int elemento = vector[indice];
int pos = indice - 1;
while ((pos >= 0) && (elemento < vector[pos]))
{
vector[pos + 1] = vector[pos];
pos = pos - 1;
}
vector[pos + 1] = elemento;
}
[Haz clic aquí y escribe el título de la unidad didáctica]
6
}
int main()
{
imprimeContenidoVector();
ordenaInsercionDirecta();
imprimeContenidoVector();
return 0;
}
___________________________________________________________
Lección 3 – Inserción binaria
1
Implementa el algoritmo de inserción binaria en un lenguaje
de tu elección y compara su eficiencia con la del algoritmo de
inserción binaria para datos ordenados y aleatorios.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int vector[] = {10, 99, 35, 25, 3, 7, 80, 22, 45, 23};
int tamanoVector = 10;
void ordenaInsercionBinaria()
{
int indice;
for(indice = 1; indice < tamanoVector; indice++)
{
int elemento = vector[indice];
int bajo = 0;
int alto = indice - 1;
int pos;
while(bajo <= alto)
{
int medio = (alto + bajo) / 2;
if(elemento < vector[medio])
{
alto = medio - 1;
}
else
{
bajo = medio + 1;
}
}
for(pos = indice - 1;pos >= bajo; pos--)
[Haz clic aquí y escribe el título de la unidad didáctica]
7
{
vector[pos + 1] = vector[pos];
}
vector[bajo] = elemento;
}
}
int main()
{
imprimeContenidoVector();
ordenaInsercionBinaria();
imprimeContenidoVector();
return 0;
}
___________________________________________________________
Lección 4 – Selección directa
1
Implementa el algoritmo de selección directa en un lenguaje
de tu elección.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int vector[] = {10, 99, 35, 25, 3, 7, 80, 22, 45, 23};
int tamanoVector = 10;
void ordenaSeleccionDirecta()
{
int indice;
for(indice = 0; indice < tamanoVector - 1; indice++ )
{
int pos;
int menor = indice;
for(pos = indice + 1; pos < tamanoVector; pos++)
{
if(vector[pos] < vector[menor])
{
menor = pos;
}
}
if(menor != indice)
{
int tmp = vector[indice];
[Haz clic aquí y escribe el título de la unidad didáctica]
8
vector[indice] = vector[menor];
vector[menor] = tmp;
}
}
}
int main()
{
imprimeContenidoVector();
ordenaSeleccionDirecta();
imprimeContenidoVector();
return 0;
}
___________________________________________________________
Lección 5 – Algoritmo de la burbuja
1
Implementa el algoritmo de la burbuja en un lenguaje de tu
elección y pruébalo para distintos tipos de vectores de
entrada.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int vector[] = {10, 99, 35, 25, 3, 7, 80, 22, 45, 23};
int tamanoVector = 10;
void ordenaBurbuja()
{
int indice;
for(indice = 0; indice < tamanoVector; indice++ )
{
int pos;
for(pos = tamanoVector - 1; pos > indice; pos-- )
{
if(vector[pos] < vector[pos - 1])
{
int tmp = vector[pos];
vector[pos] = vector[pos - 1];
vector[pos - 1] = tmp;
}
}
}
}
[Haz clic aquí y escribe el título de la unidad didáctica]
9
int main()
{
imprimeContenidoVector();
ordenaBurbuja();
imprimeContenidoVector();
return 0;
}
___________________________________________________________
Lección 6 – Algoritmo de la burbuja mejorado
1
Implementa el algoritmo de la burbuja mejorado en un
lenguaje de tu elección y compara su eficiencia con el
algoritmo de la burbuja.
Dado que no existe un tipo booleano en C, utilizaremos una variable de tipo
entero cuyo valor estableceremos en 0 para indicar el valor falso y en 1 para indicar
el valor verdadero.
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
int vector[] = {10, 99, 35, 25, 3, 7, 80, 22, 45, 23};
int tamanoVector = 10;
void ordenaBurbujaMejorado()
{
int ORDENADO = 0;
int indice = 1;
while((indice < tamanoVector) && !ORDENADO)
{
int pos;
ORDENADO = 1;
for(pos = tamanoVector - 1; pos >= indice; pos-- )
{
if(vector[pos] < vector[pos - 1])
{
int tmp = vector[pos];
vector[pos] = vector[pos - 1];
vector[pos - 1] = tmp;
ORDENADO = 0;
}
}
indice += 1;
}
[Haz clic aquí y escribe el título de la unidad didáctica]
10
}
int main()
{
imprimeContenidoVector();
ordenaBurbujaMejorado();
imprimeContenidoVector();
return 0;
}
___________________________________________________________
Unidad 5 – Algoritmos de mezcla
Lección 2 – Mezcla simple
1
El algoritmo presentado es una implementación genérica
y simplificada. ¿Puedes identificar en qué circunstancias
falla? (Pon a prueba el funcionamiento del pseudocódigo con
pequeñas listas de números que simulen ser ficheros, tal y como
se hace en el siguiente ejemplo)
Tal y como está implementado, se producirían fallos si los archivos no
contienen ningún dato o si sólo uno de ellos contiene datos en cuyo caso no se
escribiría el primero de los datos.
Unidad 6 – Algoritmos heurísticos
Lección 1 – Búsqueda exhaustiva
1
Escribe un algoritmo basado en la búsqueda exhaustiva que
muestre en pantalla los divisores enteros de un número.
Pruébalo con distintas entradas como 1, 5, 123, 65535, 1024768…
Fíjate que hemos implementado el algoritmo de forma más sencilla que en el
pseudocódigo de la lección, donde se muestra un algoritmo genérico; por ejemplo,
esSolución está representado por la sentencia
if((numero % i) == 0)
En esta sentencia comprobamos si al dividir numero entre i el resto es 0 (el
operador módulo efectúa esta operación). En tal caso, podemos afirmar que i es un
divisor de numero.
[Haz clic aquí y escribe el título de la unidad didáctica]
11
Algoritmo en C________________________________________________
#include <stdio.h>
#include <stdlib.h>
void divisoresEnteros(int numero)
{
int i;
for(i = 1; i < numero; i++)
{
if((numero % i) == 0)
{
printf("Divisor de %d: %d\n", numero, i);
}
}
}
int main()
{
divisoresEnteros(123235);
return 0;
}
___________________________________________________________
[Haz clic aquí y escribe el título de la unidad didáctica]
12
Descargar