Práctica 8 Abril 26, 2008
Posted by beceoca in Posts normales.add a comment
La octava práctica trata sobre la Tabla hash y la recursirsividad
Pasamos ahora a definir estos dos conceptos.
Tabla Hash
La principal función de esta clase es asociar un valor a una clave, y sus principales métodos son:
- put(clave, valor): añade una clave y un valor asociado.
- get(clave): introduciendo una clave te devuelve su valor.
Recursividad
Se dice que un objeto es recursivo si forma parte de sí mismo o de define en función de sí mismo.Esto quiere decir que una vez dentro de un método, por ejemplo, puedes llamarse así mismo con otros parámetros como valores de entrada a ese método.
La recursividad tiene bastantes aplicaciones, como por ejemplo obtener un factorial, una serie, etc
Es necesiario establecer una condición de parada, para finalizar el algoritmo y que no se convierta en un bucle infinito.
EJERCICIO 1
Consiste en definir una tabla Hash que contenga 10 palabras claves con sus 10 valores asociados respectivamente, de forma que cuando introduzcas la sentencia get(clave), obtengas su valor.
Para ello, debemos importar el paquete “java.util.Hashtable”, y en el propio main de la clase que creamos nosotros (llamada TablaJas) creamos un objeto de la clase HashTable con nombre t.
Posteriormente introducimos las distintas claves y sus valores con el código t.put(“clave1″,”valor1″).
Finalmente para probar que las claves y los valores se han añadido correctamente imprimimos los valores asociados a cada una de las claves con System.out.println(t.get(“clave1″)).
EJERCICIO 2
Con la clase proporcionada en la práctica, se pide explicar cada uno de los métodos.
Método factorial
public long factorial(long num){
if (num==1)
return 1;
else
return (num * factorial(num-1));
}
Este método impone una condición de parada que consiste en que el parámetro num sea igual a uno, devolviéndote en este caso un uno. Si esto no se cumple te devuelve el valor de num multiplicado por el factorial del número anterior a num, es decir (num-1), hasta que llegues a la condición de parada anteriormente descrita.
Método p1
public void p1(int a){
if (a>0){
System.out.println(a);
p1(a-1);
}else{
System.out.println(“FIN”);
}
}
En este método la condición de parada es que el valor a sea menor o igual que cero, si es así imprime por pantalla “FIN”, en otro caso imprime el valor de a y vuelve a llamarse, introduciendo como parámetro de entrada el valor (a-10).
Método p2
public void p2(int a, int b){
if (a>0){
p2(a-1,b+a);
}else
System.out.println(b);
}
En este caso introducimos dos números, a y b, que si no cumplen la condicion de que a sea mayor que cero imprimirán por pantalla el número b introducido y si la cumplen se llamará sí mismo, con parámetros a-1 y b+a.
Método suma
public long suma(long [] tabla, int posActual, int tamaño){
if (posActual == tamaño -1 )
return tabla[posActual];
else
return (tabla[posActual] + suma(tabla, posActual+1, tamaño));
}
Este método suma todos los elementos de un array. Los parámetros de entrada del método son el array (tabla) anteriormente mencionado, un número posActual que indica la posición en que nos encontramos y otro tamaño que indica el tamaño del array.
La condición de parada en este caso es que el tamaño sea -1, es decir que nos encontremos en el último elemento. Si no cumple la condición de parada realiza la suma de la posición en que nos entontremos y las siguientes, para obtener finalmente el valor de la suma de todos los elementos del array tabla.
Método inverso
public void inverso(int n){
System.out.print(n % 10);
if (n>=10)
inverso(n/10);
}
El parámetro de entrada del método es un número cualquiera. El método pinta por pantalla el resto de la división del número entre 10, y si el número sigue teniendo dos cifras, es decir, es mayor o igual que 10 se vuelve a llamar con número de entrada n dividido entre 10, para obtener el siguiente número a imprimir.
Método fibonacci
public long fibonacci(long num){
if ((num == 1) || (num == 2))
return 1;
else
return (fibonacci(num-2) + fibonacci(num-1));
}
Este método requiere como parámetro de entrada un número sin decimales. La actividad que realiza es que mientra el número no sea igual a uno o a dos devuelve el resultado de llamarse a sí mismo con parámetro de entrada la suma de la llamada a sí mismo en este caso con parámetros de entrada el número del principio menos dos y el número del principio menos uno.
Por último está el método main que se encarga de hacer una prueba de todos los métodos.
EJERCICIO 3
Este ejercicio nos fue imposible de realizar por falta de tiempo, ya que los otros dos anteriores y las explicaciones del profesor para la realización de la práctica requirieron las dos horas de prácticas de las que disponíamos esa semana.
Por lo tanto nos tocará quedar algún día de la semana antes del puente para finalizarla.
Práctica 7 Abril 18, 2008
Posted by beceoca in Posts normales.2 comments
Esta práctica consiste en seguir afianzando los conceptos de algoritmia, en este caso las estructuras de datos dinámicos.
En la práctica anterior implementamos una cola de manera estática, es decir, creando un array donde almacenábamos todas las piezas creadas para su posterior gestión.
En este caso debíamos transformar la cola para hacerla de forma dinámica.
Tuvimos bastantes problemas en cuanto a esta forma de realizar las colas, como por ejemplo no dar con la forma de hacerla sin utilizar arrays, vectores, colas, etc.
Mirando en los apuntes, observamos cómo se hacía mediante una clase nodo, pero realmente no entendemos como usar ese método para realizar una cola como la que se pide en la práctica. Esperamos que mirando los blogs de los demás compañero, o acudiendo a alguna tutoría con alguno de los profesores de la asignatura, podamos empezar a entender como ir realizando la cola de esta forma.
Práctica 5 Abril 18, 2008
Posted by beceoca in Posts normales.add a comment
En la práctica 5 sólo nos dio tiempo a hacer el ejercicio 1 porque en la primera hora el profesor nos estuvo explicando los conceptos de:
Polimorfismo :que es es la capacidad de un objeto de decidir a qué método invocar en función de la posición que ocupa en la jerarquía de clases.
Sobrecarga de métodos :Se produce cuando tenemos varias implementaciones de un mismo método pero con distintos parámetros.
Sobreescritura de métodos :Se produce cuando la subclase es la que implementa el método heredado de la superclase.
Luego nos explicó el concepto de clase abstracta que es aquella que define uno o más métodos abstractos.
Un método abstracto es una declaración de una interfaz(función) pero sin implementación asociada. Se declara con la palabra clave abstract y su implementación asociada se realiza en la subclase correspondiente. A esta clase se considera como una clase ya implementada.
Por último nos explicó el concepto de:
Interfaz : que es un tipo de datos puramente abstracto que únicamente contiene métodos abstractos que no tienen implementación. Sirve para definir un comportamiento que han de cumplir los objetos que la implementen. Para ello, cualquier clase que implemente dicho interfaz lo hará mediante el uso de la palabra clave implements en la declaración de la clase y estará obligada a implementar todos los métodos de la misma. En Java sólo se puede heredar de una superclase (herencia simple), una clase sí que puede implementar cualquier número de interfaces y, además, estos pueden heredar de varios interfaces a su vez (herencia múltiple).
En el ejercicio 1, usando las soluciones de la practica anterior, teníamos que ver la implementación del método toString, y usando la herencia de clases mejorarla haciendo lo siguiente:
en las clases Miembro,Atributo, Metodo y Constructor,tuvimos que usar el comando super para heredar los atributos de la clase superior (clase) y usarlos sin necesidad de crearlos de nuevo. En el método toString de cada clase heredada introducíamos el comando.
str += super.toString(); en los componentes comunes a la clase Miembro, dejando el resto como estaba.
Por ahora es todo lo que tenemos de esta practica, ya que el juego nos quita bastante parte de nuestro tiempo. Cuando la acabemos editaremos este articulo para comentar los problemas y las soluciones a éstos que nos vayan surgiendo.
Practica 6 Abril 11, 2008
Posted by beceoca in Posts normales.2 comments
La practica trata sobre la implementación de una cola mediante un array (es decir, de forma estática).
Como hemos podido comprobar más adelante no es una forma muy correcta de crear este tipo de colas ya que para desencolar debemos mover todos los elementos una posicion, ya que la primera posición será siempre la posición 0 del array.
En un principio creamos la clase Cola que contiene los métodos encolar, desencolar, estaLlena y estaVacia.
El metodo encolar se encargará de añadir en la última posición la Pieza que le pasamos como parámetro. También sumará uno a la variable posición para que la proxima vez que añadamos algo a la cola se añada correctamente en la posicion que le toque.
Pieza contenido [];
int posicion;
int numElementos;
public Cola(int numElementos){
posicion = -1;
this.numElementos = numElementos;
contenido = new Pieza [numElementos];
}
El método desencolar es la operación contraria a encolar y su función será devolverte el elemento que se encuentre en la posición 0 del array y desplazarte los demás para que la proxima vez que tengas que sacar algo encuentres algo en la primera posición. No debemos olvidar restar uno a la variable posición, para que apunte a la nueva última posición.
public void encolar(Pieza p){
posicion++;
contenido[posicion] = p;
}
public Pieza desencolar(){
Pieza elemento = contenido[0];
for(int i = 1; i<(numElementos-1) ;i++){
contenido [i] = contenido [i-1];
}
posicion–;
contenido [(numElementos-1)] = null;
return elemento;
}
Los métodos estaVacia y estaLlena te indican si la cola está vacía o llena respectivamente. Para ello si la variable posición es -1 (no hay nada en la posición 0 del array) te indicará que la cola está vacia y si es igual que (numeroElementos-1)(es decir, ultima posicion del array) te dirá que la cola está llena.
public boolean estaVacia(){
//Si no hay nada en la cola te devolverá true, si hay algo te devolverá false
return (posicion == -1);
}
public boolean estaLlena(){
// Si la ultima posicion es != de nulo te devolverá true,
//si es igual a nula significa que en la ultima posicion no hay nada y por lo tanto no esta llena y devuelves false
return (contenido[(numElementos-1)] != null);
}
Posteriormente creamos la clase Pieza, que contiene tres atributos (tipo, x e y, siendo x e y la posicion de la pieza que en nuestro caso inicializaremos a 0 en el constructor de la clase). También contiene un método llamado mover que en este caso imprime por pantalla la frase “La pieza está quieta”. Y por último contiene un método toString que nos devuelve “La pieza es del tipo: “+tipo+”. Y su posicion es: (“+x+”, “+y+”)”, siendo en este caso tipo el tipo de pieza que sea, y x e y la posición de la pieza.
public class Pieza{
char tipo;
int x;
int y;
Pieza (char tipo){
this.tipo = tipo;
x = 0;
y = 0;
}
public void mover(){
System.out.println(“La pieza está quieta”);
}
public String toString(){
return(“La pieza es del tipo: “+tipo+”. Y su posicion es: (“+x+”, “+y+”)”);
}
}
La clase Prueba contiene en su main la creación de varias piezas de distinto tipo, que en nuestro caso son las clases creadas en la segunda parte de la práctica y de tipo T, P, O, etc a las que no hace falta pasarles el tipo ya que heredan de la clase Pieza y en sus respectivos constructores se indica, tambien creamos un objeto de la clase Pieza en el cual tuvimos que introducirle el tipo, ya que en este caso sí hace falta indicárselo.
Añadimos las piezas a la cola e invocamos los métodos estaLlena y estaVacia, siendo las respuestas true y false en este caso. Posteriormente desencolamos todos los elementos y volvimos a preguntar estaLlena y estaVacia, en este caso con respuesta false y true.
public class Prueba{
public static void main (String [] args){
Pieza p1 = new Pieza(‘P’);
System.out.println(p1.toString());
PiezaT p2 = new PiezaT();
System.out.println(p2.toString());
PiezaO p3 = new PiezaO();
System.out.println(p3.toString());
PiezaL p4 = new PiezaL();
System.out.println(p4.toString());
PiezaI p5 = new PiezaI();
System.out.println(p5.toString());
PiezaS p6 = new PiezaS();
System.out.println(p6.toString());
PiezaJ p7 = new PiezaJ();
System.out.println(p7.toString());
Cola c = new Cola(7);
c.encolar(p1);
c.encolar(p2);
c.encolar(p3);
c.encolar(p4);
c.encolar(p5);
c.encolar(p6);
c.encolar(p7);
System.out.println(“Esta llena?”+c.estaLlena());
System.out.println(“Esta vacía?”+c.estaVacia());
c.desencolar();
c.desencolar();
c.desencolar();
c.desencolar();
c.desencolar();
c.desencolar();
c.desencolar();
System.out.println(“Esta llena?”+c.estaLlena());
System.out.println(“Esta vacía?”+c.estaVacia());
}
}
Ponemos un ejemplo de una de las clases heredadas de la clase Pieza
public class PiezaI extends Pieza{
public PiezaI(){
super(‘I’);
}
public String toString(){
return(super.toString());
}
public static void main(String args[]){
}
}