martes, 16 de febrero de 2021
Recursión
Un método recursivo es aquel que, en el cuerpo del mismo, se invoca a sí mismo.
Ejemplo de aplicaciones:
Examinar todos los ficheros de un directorio examinando a su vez todos los ficheros de sus subdirectorios.
Buscar el significado de una palabra de un diccionario.
Es una herramienta muy potente y peligrosa.
Ej. obtener la suma de n y los n-1 numeros anteriores a n:
public static long suma(long n) {
long s = 0;
//caso base n = 1
if (n == 1) return s= 1;
else return s= suma(n-1)+n;
}
Se debe tener siempre un caso base que se resuelva sin recursión.
El caso general debe ir acercándose paso a paso al caso base, sin pasarse.
//Otro ej.Imprime un entero en cualquier base entre 2 y 16.
public static final String tablaDigitos = "0123456789abcdef";
public static final int maxBase = tablaDigitos.length();
//Metodo recursivo:
public static void imprimeEnteroEnCualquierBase(int n, int b) {
if(n>=b) imprimeEnteroEnCualquierBase( n/b, b);
System.out.print(tablaDigitos.charAt(n%b));
}
//Metodo guia:
public static void imprimeEntero(int n, int b){
if(b<=1 || b > maxBase)
System.err.println("Base no correcta. "+b);
else
if (n<0) { n=-n;
System.out.println("ha puesto un numero negativo");
}
imprimeEnteroEnCualquierBase(n,b);
}
sábado, 6 de febrero de 2021
Estructuras de datos lineales.
Estructuras de datos lineales:
Se llaman tipos de datos lineales los que estan formados por secuencias de datos de un mismo tipo.
Se distinguen tres tipos de linealidades o secuencias: pilas, colas y listas con puntos de interés.
Estas estructuras de datos lineales se pueden implementar con arrays o con elementos enlazados, que ahora explicaremos.
Con arrays: los elementos de la secuencia se disponen sucesivamente en los distintos componentes de un array lo suficientemente grande para que quepan e incluso sobren componentes, de modo que si el tamaño del array es m, en numero de elementos de la secuencia introducidos sean n, de modo que n <= m;
Con elementos enlazados -secuencias enlazadas-.
Vamos a estudiar como se implementa una secuencia enlazada:
Un elemento u objeto de una secuencia enlazada es un objeto muy abstracto, consta de dos variables una que puede ser valores de cualquier tipo de dato, siempre del mismo tipo, y la siguiente variable que forma parte del Nodo, que así se llama el elemento de la secuencia, es un dato que contiene la referencia o direccion de memoria del heap, del nodo previamente creado.
NODO:la clase Nodo.
Es la estructura mínima, elemental, un solo objeto de una secuencia.
Consta de un dato del tipo que sea (int, double, String, twit, ... ) eso sí, todos serán del mismo tipo. Y de otro dato donde se guarda la referencia que tiene en el heap el nodo anterior.
Sea la clase NodoInt -nodos con datos de enteros. Sus atributos estan formado, como hemos dicho, por dos valores, uno un dato entero y otro por un dato que es la referencia de la memoria del nodo anterior. (Al implementar la clase, esta primera refenrcia no existirá, pues el primer nodo no contendrá, en su doto referencia correspondiente, el valor de ningun otro nodo, por ser este el primero. Pero a partir del segundo, en este atributo, se guardarán las referencias de los anteriores; veamos:
public class NodoInt{
private int dato;
private NodoInt sec;
public NodoInt(int d){
this.dato = d;
this.sec = null;
}
public NodoInt(int d,NodoInt sec){
this.dato = d;
this.sec = sec;
}
public static void main(String[] arg){
NodoInt sec = null;
sec = new NodoInt(10);
sec = new NodoInt(20,sec);
sec = new NodoInt(30,sec);
sec = new NodoInt(40,sec);
sec = new NodoInt(50,sec);
sec = new NodoInt(60,sec);
sec = new NodoInt(70,sec);
//imprimir(sec);
//saturar(60,sec);
//buscar(30,sec);
//buscar(sec,4);//Este método, que tiene el mismo nombre que el anterior, al cambiar los parametros formales,
//está implementado de forma distinta: obtiene el valor de d en un nodo iésimo.
//cambiar(30,10000,sec);
insercion(sec,25);
}
//podemos ir implementando los métodos de recorridos, búsquedas, inserción, eliminación, ... que consideremos oportunos para manipular la secuencia enlazada.
public static void imprimir(NodoInt sec){
NodoInt aux = sec;
while(aux!=null){
System.out.println(aux.dato);
aux=aux.sec;
}
}
public static void saturar(int n,NodoInt sec){
NodoInt aux = sec;
while(aux!=null){
if(aux.dato>n)aux.dato=n;
System.out.println(aux.dato);
aux = aux.sec;
}
}
public static void buscar(int n, NodoInt sec){
NodoInt aux = sec;
while(aux!=null&&aux.dato!=n){
aux = aux.sec;
}
System.out.println(aux.dato);
}
public static int buscar(NodoInt sec,int i){
NodoInt aux = sec; int k =0;
while(aux!=null&&k=d:
while (aux!=null &&aux.dato
martes, 2 de febrero de 2021
Excepciones.
Hemos dicho que hay tres tipos de errores en programación: errores que se detectan al compilar, por lo que se corrigen inmediatamente; errores de ejecución, que producen una ruptura en la ejecución del programa; y errores lógicos, que son indetectables, y producen resultados falsos e imprevisibles. Los que pueden tener un tratamiento de entre los errores de ejecución son los llamados excepciones, en cambio, los llamados propiamente errores, no tienen tratamiento. Los errores y excepciones -errores de ejecución- generan al producirse objetos de la clase específica de ese error. Nosotros estudiaremos los de las subclases de Exception, pues son recuperables.
Nos centraremos, de entre la clase exception, en las IOException y RuntimeException.
LANZAR UNA EXCEPCIÓN.
Cuando se produce un error de ejecución, el ordenador lanza una excepción, un objeto de una clase, y se interrumpe su ejecución. El programador puede también provocar el lanzamiento de una excepción, con la instrucción
throw e; siendo e un objeto de la clase de excepción que interese.
Ej:
Scanner t= new Scanner(System.in);
System.out.println("Introduzca la hora, -entre 0 y 23-");
int h = t.nextInt();
if (h < 0 || h>23){
throw new InputMismatchException( "Valor incorrecto ");
}
El ordenador lanza una excepción, bien de modo propio, bien provocada por el programador. El siguiente paso es
CAPTURA DE LA EXCEPCIÓN:
Si no se gestiona la excepción lanzada se produce una terminación abrupta del programa. Java dispone de una instrucción que permite gestionar las excepciones lanzadas: try-catch o try-catch-finally.
Con esta instrucción se CAPTURA la excepción del tipo, y se continúa la ejecución del programa como se desee.
Ejemplo:
try {
código donde se pueden producir excepciones
}
catch(TipoExcepcion1 e1){
lo que se hace con ello
}
catch(TipoExcepcion2 e2){
lo que se hace con ello
}
..
finally {
bloque opcional. Se ejecuta siempre, tanto si se han producido excepciones como si no.
}
Hemos visto hasta ahora que errores de ejecución lanzan excepciones, que también el programador puede producir el lanzamiento de excepciones como la instrucción throw e, el tipo de excepción. Hemos visto así mismo como se capturan con la instrucción try-catch: try como el bloque matriz donde se genera la excepción y catch que captura propiamente la excepción de un tipo concreto. .. puede haber tantos catchs como tipos distintos de excepciones se puedan generar.
Vamos a ver la PROPAGACIÓN de excepciones: tratar la excepción en un lugar distinto de donde se ha producido.
Java permite añadir cláusulas en las cabeceras de los métodos para que se propaguen las excepciones que se generen en su interior. Esta cláusula es throws TipoException, pudiendo haber más de una excepción, separadas con comas.
Ejemplo:
public static void escribeComp(int i, int[] a) throws ArrayIndexOutOfBoundsException {
System.out.println(a[i]); }
public static void main(String args[]){
int [] v = new int[100];
Scanner t = new Scanner(System.in);
boolean lecturaCorrecta = false; int n = 0;
do { try { System.out.print("Índice (entre 0 y 99)? ");
n = t.nextInt();
escribeComp(n,v);//puede dar la excepción de fuera de rango
lecturaCorrecta = true;
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println("error, "+ n +" incorrecto, pruebe otra vez. ");
}
while(!lecturaCorrecta);
}
si llega aquí es que ha hecho una lectura correcta!
el while lo que hace es que se repita la entrada si la lectura no ha sido correcta, pues el valor de la guarda es true: niega una negación.
y mientras la guarda sea true repite el bucle.
ds del método y antes del bloque de instruccione,
pone el try-catch en el do!
Suscribirse a:
Comentarios (Atom)
