Manual de Prácticas-ProgramaciónII
Manual de Prácticas-ProgramaciónII
Manual de Prácticas de
Programación II
Aparatados Pág.
PRIMERA SECCIÓN
Lineamientos del Laboratorio
Presentación (Introducción)
Sistema de Evaluación
SEGUNDA SECCIÓN
Compendio y Presentación: 6
Práctica 1: Herencia simple 7
Objetivo 7
Introducción Teórica 7
Ejercicio para realizar 11
Evaluación: 11
Evidencia: 11
Referencias 11
Práctica 2: Interfaces y Clases abstractas 12
Objetivo: 12
Introducción Teórica: 12
Ejemplo 13
Ejercicios 17
Evidencia de trabajo: 18
Referencias: 18
Práctica 3: Colecciones de Objetos e Iteradores 19
Objetivo: El alumno conocerá y usará las Colecciones de Objetos de uso más
común en java. 19
Introducción Teórica 19
Ejemplo 22
Procedimiento 26
Evaluación y evidencia: 26
Referencias 26
Práctica 4: Tiempos de ejecución de algoritmos de ordenamiento y búsqueda.
27
Introducción Teórica: 27
Procedimiento 31
Evaluación: 32
Evidencia para obtener: 32
Referencias 32
Práctica 5: Uso de Pilas 34
Objetivo: 34
Introducción Teórica: 34
Ejercicio 39
Evaluación 39
Evidencia 39
Referencias 39
Practica 6: Uso de Colas 40
Objetivo: 40
Introducción Teórica: 40
Ejemplo 42
Ejercicio a realizar 45
Evaluación 45
Evidencia: 45
Referencias 45
Práctica 7: Árboles 46
Objetivo: 46
Introducción Teórica: 46
Ejemplo 50
Ejercicio a realizar 53
Evaluación: 53
Evidencia: 53
Práctica 8: Manejo de archivos y procesamiento de datos. 54
Introducción Teórica: 54
Procedimiento 58
Evaluación: 59
Evidencia a obtener: 59
Referencias 59
ANEXO 60
Universidad Autónoma del Estado de México Centro
Universitario UAEM Texcoco
REGLAMENTO PARA ACCESO Y USO DE LOS LABORATORIOS Y SALAS DE CÓMPUTO
1.-Los servicios de sala de uso general, laboratorios de microcomputadoras y especializados son para
uso exclusivo de horas clase y procedimientos institucionales que los requieran.
3.-Queda estrictamente prohibido introducir bebidas y/o alimentos en los laboratorios de cómputo.
4.-Queda estrictamente prohibido fumar dentro de las instalaciones de los Laboratorios de Cómputo.
5.-Los objetos personales (mochilas, bolsas, etc.) de los usuarios no deben colocarse sobre la mesa del
equipo de cómputo.
6.-Si hay necesidad de instalar software específico, deberá solicitarse a los RTIC (Responsable de
Tecnologías de la Información y Comunicaciones) con 5 días hábiles de anticipación, proporcionando lo
requerido (software, licencia en caso de no ser software libre y método de instalación en caso de
requerir alguna configuración especial).
7.-Toda información deberá ser almacenada en alguna unidad de almacenamiento externo propio del
usuario, ya que los equipos cuentan con un freeze que al reiniciar el equipo restaura su
configuración anterior borrando cambios o información guardada en dicho equipo.
9.-Cada equipo solo podrá ser utilizado por dos personas como máximo.
10.- Por ningún motivo se permitirá el acceso a los alumnos al Laboratorio sin la presencia de su
profesor.
11.-El profesor deberá permanecer dentro del espacio durante su estancia hasta que el último alumno
se retire o finalice la sesión de laboratorio.
13.-Toda persona que sea sorprendida sustrayendo accesorios, equipamiento, mobiliario, cambiando
configuraciones y/o desconectando equipo de cómputo, será presentada ante la autoridad
competente.
14.-El uso de internet en el laboratorio deberá ser requerido y justificado al iniciar la sesión por el
profesor y este será de uso estrictamente académico por lo tanto no se podrá acceder a
ningún tipo de chat, páginas de contenido pornográfico, snuff, o páginas de descarga, música, videos,
redes sociales,
deportes y/o juegos a menos que el programa de estudios lo especifique.
15.-La tolerancia de acceso a los laboratorios es de 15 minutos después de la hora marcada, en caso de
que haya alguna solicitud de uso de laboratorio, este será asignado por ausencia de grupo o profesor.
16.-En caso de existir algún desperfecto, daño o faltante con respecto a equipo de cómputo, mobiliario
o infraestructura de sala de uso general y Laboratorios, deberá de ser notificado al RTIC y/o personal a
cargo por parte del profesor para levantar el reporte y dar el seguimiento necesario a este.
17.-Es responsabilidad propia del usuario todo objeto olvidado dentro del laboratorio.
19.-El acceso a los laboratorios será proporcionado única y exclusivamente por el RTIC y/o el personal a
cargo.
20.-Es responsabilidad del profesor solicitar y entregar la(s) listas de registro debidamente llenadas
(una lista por laboratorio), así como notificar de inmediato cualquier faltante, anomalía o
desperfecto encontrado o suscitado durante su sesión, de lo contrario se hará responsable al
grupo anterior al momento del reporte.
22.- El profesor deberá cerrar la(s) puertas del Laboratorio colocando seguro y notificar a la persona a
cargo de su salida la cual deberá ser con al menos cinco minutos de anticipación de la hora límite de su
clase para que el Laboratorio sea revisado por el RTIC y/o el personal a cargo.
NOTA: En caso de incumplir el presente reglamento, se girará el reporte a las autoridades universitarias
correspondientes.
Compendio y Presentación:
Las necesidades contemporáneas de la industria del software son cada vez más
demandantes y complejas. La industria y la empresa requieren sistemas
computacionales que de forma dinámica gestione información importante.
Para hacer frente a las demandas de la industria es importante que los profesionistas
conozcan los conceptos básicos de complejidad computacional, los algoritmos de
ordenamiento, de búsqueda, del almacenamiento permanente de la información y los
principios de operación de las estructuras dinámicas lineales y no lineales.
Las prácticas aquí planteadas llevarán al alumno poco a poco a dominar los
conocimientos necesarios para aplicar en los programas computacionales más
significativos. El estudio de los temas de la unidad puede ampliarse de acuerdo con las
decisiones del profesor con apoyo en las referencias que se anexan en el documento.
Práctica 1: Herencia simple
Objetivo
Identificar y usar las propiedades de la herencia simple como estrategia de
reutilización de código
Introducción Teórica
La herencia provee el mecanismo más simple para especificar una forma alternativa de
acceso a una clase existente, o para definir una nueva clase que añada nuevas
características a una clase existente. Esta nueva clase se denomina subclase o clase
derivada de la clase existente, superclase o clase base. Las clases que están en la
parte inferior en la jerarquía heredan de las clases que están en la parte superior de la
jerarquía.
En una jerarquía de clases, una clase es tanto más especializada cuanto más alejada
esté de la raíz. Y es tanto más genérica cuando más cerca esté de la raíz. Por ejemplo,
la clase Object es la raíz de la jerarquía de las clases de Java y sólo define los atributos
y comportamientos comunes a todas las clases.
Generalmente, la razón de la existencia de una clase genérica es proporcionar los
atributos y comportamientos que serán compartidos por todas las subclases. En la
siguiente imagen se observa la clase Mueble que representa todas las propiedades y
métodos comunes de los muebles que se venden en una mueblería y la silla representa
las propiedades específicas de todas las sillas de la mueblería. Obsérvese que se usa
la línea que significa es un. para indicar que la Silla es un Mueble. Para codificar es
importante reconocer la jerarquía de las clases ya que se deben codificar primero las
clases de mayor jerarquía y al final las clases más especializadas.
A través de la herencia, la POO permite definir la clase Silla como una extensión de
Mueble. Los siguientes puntos resumen las reglas a tener en cuenta cuando se define
una subclase:
1. Una subclase hereda todos los miembros de su superclase, excepto los
constructores. Una consecuencia inmediata de esto es que la estructura interna de
datos de un objeto de una subclase estará formada por los atributos que ella define y
por los heredados de su superclase. Una subclase no tiene acceso directo a los
miembros privados de su superclase. Una subclase si puede acceder directamente a
los miembros públicos y protegidos de su superclase, también puede acceder a los
miembros predeterminados
2. Una subclase puede añadir sus propios atributos y métodos. Si el nombre de alguno
de estos miembros coincide con el de un miembro heredado, este último queda oculto
para la subclase, que se traduce en que la subclase ya no puede acceder directamente
a ese miembro.
3. Los miembros heredados por una subclase pueden, a su vez, ser heredados por más
subclases de ella. A esto se le llama programación de herencia. Los métodos de una
subclase no tienen acceso a los miembros privados de su superclase, pero sí lo tiene a
sus miembros protegidos y públicos, y si la subclase pertenece al mismo paquete que la
superclase, también tiene acceso a sus miembros predeterminados. Si una subclase
tuviera acceso a los miembros privados de su superclase, entonces cualquiera podría
acceder a los miembros privados de una clase, simplemente derivando una clase de
ella. Consecuentemente, si una subclase quiere acceder a los miembros privados de
su subclase, debe hacerlo a través de la interfaz pública, protegida, o predeterminada
en su caso, de dicha superclase.
Constructores de las subclases.
Cuando se tiene una relación subclase-superclase, al momento de construir un objeto
de una subclase, se invoca a su constructor, que a su vez invoca al constructor sin
parámetros de la superclase, que a su vez invoca al constructor de su superclase, y así
sucesivamente.
Ahora bien, si se han definido constructores con parámetros tanto en subclases como
en superclases, tal vez se desee construir un objeto de la subclase iniciándolo con unos
valores predeterminados. Esto permite que el constructor de subclase invoque
explícitamente al constructor de la superclase. Esto se hace utilizando la palabra
reservada “super”.
public nombre_subclase (lista de parámetros incluyendo los que se requieren para la super clase){
super(lista de parámetros);
//cuerpo del constructor de la subclase.
}
Esta línea llama al constructor de Mueble, superclase de Silla. Por lo que Silla debe
tener un constructor con cinco parámetros del tipo de los argumentos especificados
Cuando se crea un objeto de una subclase, por ejemplo “sillaSecretarial1” o
“sillaEjecutiva2”, primero se construye la porción del objeto correspondiente a su
superclase y a continuación la porción del objeto correspondiente a la subclase.
Ejemplo de Codificación
Con base en el diagrama anterior el código queda de la siguiente forma:
Código de la clase Mueble
public class Mueble {
//Atributos
private String numSerie; private String modelo;
private float precioCosto; private float precioVenta;
private int existencias;
//Constructor
public Mueble(String numSerie, String modelo, float precioCosto, float precioVenta, int existencias) {
this.numSerie = numSerie; 10
this.modelo = modelo;
this.precioCosto = precioCosto;
this.precioVenta = precioVenta;
this.existencias = existencias;
}
//Setters y Getters
public String getNumSerie() { return numSerie; }
public void setNumSerie(String numSerie) { this.numSerie = numSerie; }
public String getModelo() { return modelo; }
public void setModelo(String modelo) { this.modelo = modelo; }
public float getPrecioCosto() { return precioCosto; }
public void setPrecioCosto(float precioCosto) { this.precioCosto = precioCosto; }
public float getPrecioVenta() { return precioVenta; }
public void setPrecioVenta(float precioVenta) { this.precioVenta = precioVenta; }
public int getExistencias() { return existencias; }
public void setExistencias(int existencias) { this.existencias = existencias; }
@Override
public String toString() {
return "Mueble{" + "numSerie=" + numSerie + ", modelo=" + modelo + ", precioCosto=" + precioCosto
+ ", precioVenta=" + precioVenta + ", existencias=" + existencias + '}';
} }
@Override
public String toString() {
String datosDelPadre=super.toString();
String datosDeHijo="Silla{" + "material=" + material + ", numPatas=" + numPatas + '}';
return datosDeHijo.concat(datosDelPadre); } }
Ejercicio para realizar 11
Con base en el ejemplo anterior codifica la siguiente jerarquía de clases, por el poco
espacio no se incluyeron los métodos getters y setters de las clases, pero en el código
no debes omitirlos
Incluye la codificación de la clase main
Evaluación:
Aciertos: 10 puntos por clase codificada
Evidencia:
Jerarquía terminada y ejecución del proyecto evaluado por el profesor
Referencias
Sznajdleder, Pablo Augusto, Java a fondo: estudio del lenguaje y desarrollo de aplicaciones. - 2a ed. Buenos
Aires: Alfaomega Grupo Editor Argentino, 2013, 456 p; ISBN 978-987-1609-36-9
Guardati Buemo Silvia, (2007). “Estructura De Datos Orientada A Objetos, Algoritmos Con C++]”, Pearson
Educación.
Guardati Buemo Silvia. (2016). Estructuras de datos básicas programación orientada a objetos con
Java. Alfaomega Grupo Editor
Práctica 2: Interfaces y Clases abstractas 12
U. Competencia 1: Conceptos suplementarios de programación orientada a objetos
Duración Estimada: 2 sesión de 50 minutos
Objetivo:
Conocer y usar las clases abstractas y las Interfaces.
Introducción Teórica:
Una de las características más útiles de cualquier lenguaje orientado a objetos es la
posibilidad de declarar clases que definen como se utilizan solamente, sin tener que
implementar métodos. Esto es muy útil cuando la implementación es específica para
cada usuario, pero todos los usuarios tienen que utilizar los mismos métodos. Un
ejemplo de clase abstracta en Java es la clase Graphics:
public abstract class Graphics {
public abstract void drawLine( int x1,int y1,int x2, int y2 );
public abstract void drawOval( int x,int y,int width, int height );
public abstract void drawArc( int x,int y,int width, int height,int startAngle,int arcAngle );
...
}
Los métodos se declaran en la clase Graphics, pero el código que ejecutará el método
está en algún otro sitio:
public class MiClase extends Graphics {
public void drawLine( int x1,int y1,int x2,int y2 ) {
<código para pintar líneas -específico de
la arquitectura->
}
}
Cuando una clase contiene un método abstracto tiene que declararse abstracta. No
obstante, no todos los métodos de una clase abstracta tienen que ser abstractos. Las
clases abstractas no pueden tener métodos privados (no se podrían implementar) ni
tampoco estáticos. Una clase abstracta tiene que derivarse obligatoriamente, no se
puede hacer un new de una clase abstracta.
Una clase abstracta en Java es lo mismo que en C++ virtual func() = 0; lo que obliga a
que al derivar de la clase haya que implementar forzosamente los métodos de esa clase
abstracta.
Interfaces: Los métodos abstractos son útiles cuando se quiere que cada
implementación de la clase parezca y funcione igual, pero necesita que se cree una
nueva clase para utilizar los métodos abstractos.
Los interfaces proporcionan un mecanismo para abstraer los métodos a un nivel
13
superior. Una Interface contiene un conjunto de métodos que se implementan en otras
clases de acuerdo a las necesidades específicas de cada clase implementadoras. Los
métodos de una clase son public, static y final.
La principal diferencia entre Interface y abstract es que un Interface proporciona un
mecanismo de encapsulación de los protocolos de los métodos sin forzar al usuario a
utilizar la herencia.
Ejemplo
package restaurante;
package restaurante;
import java.util.Date;
//Setters y Getters
public String getNombre() { return nombre; }
public void setNombre(String nombre) { this.nombre = nombre; }
public String getRfc() { return rfc; }
public void setRfc(String rfc) { this.rfc = rfc; }
public Date getFecIngreso() { return fecIngreso; }
public void setFecIngreso(Date fecIngreso) { this.fecIngreso = fecIngreso; }
public float getComisionS() { return comisionS; }
public void setComisionS(float comisionS) { this.comisionS = comisionS; }
public float getPagoGanado() { return pagoGanado; }
public void setPagoGanado(float pagoGanado) { this.pagoGanado = pagoGanado; }
@Override
public String toString() {
return "Vendedor{" + "nombre=" + nombre + ", rfc=" + rfc + ", fecIngreso=" + fecIngreso + ",
comisionS=" + comisionS + ", pagoGanado=" + pagoGanado + '}';
}
import java.util.ArrayList;
import java.util.Date;
public class Restaurante {
Ejecución de código:
Referencias:
Sznajdleder, Pablo Augusto, Java a fondo: estudio del lenguaje y desarrollo de aplicaciones. - 2a ed. Buenos
Aires: Alfaomega Grupo Editor Argentino, 2013, 456 p; ISBN 978-987-1609-36-9
Guardati Buemo Silvia, (2007). “Estructura De Datos Orientada A Objetos, Algoritmos Con C++]”, Pearson
Educación.
Guardati Buemo Silvia. (2016). Estructuras de datos básicas programación orientada a objetos con
Java. Alfaomega Grupo Editor
19
Práctica 3: Colecciones de Objetos e Iteradores
U. Competencia 1: Conceptos suplementarios de programación orientada a objetos
Introducción Teórica
En prácticamente todos los lenguajes de computación existen estructuras para
almacenar colecciones de datos. Esto es, una serie de datos agrupados a los que se
puede hacer referencia con un único nombre. Ejemplo de ello son los arreglos, el
problema de los arreglos es que son estructuras estáticas, esto significa que se debe
saber el número de elementos que formarán parte de esa colección a priori, es decir,
en tiempo de compilación hay que decidir el tamaño del arreglo.
Las estructuras dinámicas tienen la ventaja de que sus integrantes se deciden en
tiempo de ejecución y que el número de elementos es ilimitado. Estas estructuras
dinámicas son clásicas en la programación y son las colas, pilas, listas enlazadas,
árboles, grafos, etc. En muchos lenguajes se implementan mediante punteros; como
Java no posee punteros explícitos que controlen los programadores se crearon clases
especiales para implementar estas funciones.
En Java desde la primera versión se incluyeron las clases: Vector, Stack, Hashtable,
BitSet y la interfaz Enumeration. En Java 2 se modificó este funcionamiento y se
potenció la creación de estas clases.
Interface Collection
La interfaz fundamental de trabajo con estructuras dinámicas es java.util.Collection.
Esta interfaz define métodos muy interesantes para trabajar con listas y conjuntos.
Todas las clases que implementan la Interface Collection se usan de forma similar. Lo
que cambia es la forma en que se almacenan los elementos: ordenados, con duplicidad,
con acceso basado en una clave.
Algunas características comunes de las clases heredadas de Collection:
• Los elementos de una Collection se pueden recorrer secuencialmente y son
accesibles mediante un índice.
• Map contiene pares clave-objeto, de forma que los elementos son ordenados y
son accesibles a través de sus claves.
• Para recorrer un Map debe antes extraerse de él una Collection.
• ArrayList y LinkedList pueden usarse a modo de pila, añadiendo y eliminando
elementos.
• TreeMap y TreeSet están ordenados.
20
• Set y Map no pueden tener duplicados.
Transformaciones
Se puede pasar de un tipo de estructura a otra, de forma que así se eliminen los
duplicados, se ordenen los elementos, se cree un array, etc., según sea el caso.
Cualquier tipo de Collection puede transformarse a otra Collection, simplemente al crear
una nueva instancia:
• Set set = new HashSet();
• SortedSet ss = new TreeSet(set);
• Los Map se transforman en Collection eliminando las claves:
• Collection col = tm.values();
• Cualquier Collection puede transformarse en un Array:
o Object [] obj = collection.toArray();
while(it.hasNext()){
String s=(String)it.next(); System.out.println(s);
}
Clase Stack
Es una clase derivada de la anterior usada para crear estructuras de pilas. Las pilas
son estructuras dinámicas en las que los elementos se añaden por arriba y se obtienen
primero los últimos elementos añadidos.
Clase abstracta Dictionary
La desventaja de las estructuras anteriores reside en que su manipulación es larga
debido a que el orden de la lista permanece en todo momento, lo que obliga a recorrer
la lista elemento a elemento.
La clase abstracta Dictionary proporciona la interfaz para trabajar con mapas de valores
clave. Actualmente está absolutamente reemplazado con la interfaz Map. La idea es
proporcionar estructuras con un par de valores, código - contenido. En estas estructuras
se busca el código para obtener el contenido.
Mapas
Permiten definir colecciones de elementos que poseen pares de datos clave-valor. Esto
se utiliza para localizar valores en función de la clave que poseen. Son muy interesantes
y rápidos. Es la nueva implementación de tablas hash. El objeto Map es interno a los
objetos Map y representa un objeto de par clave/valor. Esta interfaz está implementada
en la clase HashMap. Además, existe la interfaz SortedMap implementada en TreeMap.
La diferencia es que TreeMap crea un árbol ordenado con las claves (el manejo es el
mismo).
Ejemplo
package mercado;
//importer las clases necesarias para usar colecciones
import java.util.ArrayList;
import java.util.Iterator;
24
public class CControl {
//atributos
ArrayList <Producto> bolsa;
//Constructor
public CControl (ArrayList mbolsa){ this.bolsa=mbolsa; }
package mercado;
//importar las clases necesarias para usar las colecciones
import java.util.ArrayList;
import java.util.Scanner;
//modificar datos de los productos de la bolsa (en este caso el costo unitario)
Scanner leer = new Scanner(System.in);
System.out.println("Inserte el producto a modificar");
String prdBuscado=leer.nextLine();
System.out.println("Inserte el nuevo costo unitario");
float ncosto=Float.parseFloat(leer.next());
String reslMod=contr.modificaCosto(ncosto, prdBuscado);
System.out.println(reslMod);
Recuerda que puedes consultar el Anexo de información para tener más datos sobre
las colecciones
Evaluación y evidencia:
Clases codificadas y ejecución del programa calificado por el profesor
Referencias
Sznajdleder, Pablo Augusto, Java a fondo: estudio del lenguaje y desarrollo de aplicaciones. - 2a ed. Buenos
Aires: Alfaomega Grupo Editor Argentino, 2013, 456 p; ISBN 978-987-1609-36-9
Guardati Buemo Silvia, (2007). “Estructura De Datos Orientada A Objetos, Algoritmos Con C++]”, Pearson
Educación.
Guardati Buemo Silvia. (2016). Estructuras de datos básicas programación orientada a objetos con
Java. Alfaomega Grupo Editor
27
Práctica 4: Tiempos de ejecución de algoritmos de
ordenamiento y búsqueda.
U. Competencia 2: Ordenamiento y búsqueda.
Duración Estimada: 3 sesiones de 50 minutos
Introducción Teórica:
La ordenación de datos consiste en disponer o clasificar un conjunto de datos en algún
determinado orden con respecto a alguno de sus campos. Para esto existen diferentes
algoritmos que permiten el ordenamiento y estos se pueden clasificar en dos tipos:
• Ordenamiento interno.
Se lleva a cabo completamente en memoria principal. Todos los objetos que se ordenan
caben en la memoria principal de la computadora.
• Ordenamiento externo.
No cabe toda la información en memoria principal y es necesario ocupar memoria
secundaria. El ordenamiento ocurre transfiriendo bloques de información a memoria
principal en donde se ordena el bloque y este es regresado, ya ordenado, a memoria
secundaria.
Existen diferentes criterios de eficiencia para los distintos tipos de algoritmos, los cuales
son:
• Por el número de pasos
• Por el número de comparaciones entre llaves para ordenar n registros.
• De utilidad cuando la comparación entre llaves es costosa.
• Por el número de movimientos de registros que se requieren para ordenar n registros.
De utilidad cuando el movimiento de registros es costoso
Tres de los algoritmos clásicos que se pueden encontrar y desarrollar con facilidad son
28
los siguientes:
Método de la burbuja: Este método de ordenación consiste en recorrer los elementos
siempre en la misma dirección, intercambiando elementos adyacentes si fuera
necesario.
método por inserción: El método de Inserción realiza n–1 iteraciones sobre el arreglo,
dejando en la i- ésima etapa (2 ≤ i ≤ n) ordenado el subarreglo a[1..i]. La manera de
hacerlo es colocando en cada iteración el elemento a[i] en su sitio correcto,
aprovechando el hecho de que el subarreglo a[1..i–1] ya ha sido previamente ordenado.
Por otro lado se encuentran los procesos o algoritmos de búsqueda que involucran
recorrer un arreglo completo con el fin de encontrar algo. Lo más común es buscar el
menor o mayor elemento (cuando es puede establecer un orden), o buscar el índice de
un elemento determinado.
Para ello existen diversos algoritmos que varían en complejidad, eficiencia, tamaño del
dominio de búsqueda.
Los mas comunes se pueden observar a continuación.
• Peor Caso: El elemento buscado está en la última posición. Necesitando igual cantidad
de comparaciones que de elementos el arreglo.
Búsqueda binaria: Una búsqueda más eficiente puede hacerse sobre un arreglo ya
ordenado, precisamente así lo hace “Búsqueda Binaria”. La Búsqueda Binaria, compara
si el valor buscado está en la mitad superior o inferior, lo hace subdividiendo el arreglo
(divide y vencerás) y así sucesivamente hasta encontrar el valor. La eficiencia se
describe a continuación:
• Mejor Caso: El elemento buscado está en el centro. Por lo tanto, se hace una sola
comparación.
• Peor Caso: El elemento buscado está en una esquina. Necesitando log2(n) cantidad de
comparaciones.
Procedimiento
La práctica para elaborar consistirá en lograr unificar todos los métodos anteriormente
mencionados en un solo código, midiendo y comparando los tiempos de ejecución entre
estos, con la finalidad de detectar la eficiencia de uno en contra de otros, todo esto en
iguales circunstancias. El programa deberá funcionar de la siguiente manera:
0 . . . n-1
A
Ejecutar el código tantas veces sea necesario para evidenciar las diferencias de tiempo
entre cada uno de ellos en diferentes circunstancias. Es decir, probar el mejor de los
casos, el peor de los casos y el caso promedio.
Las siguientes líneas de código funcionan como guía para medir relativamente el tiempo
de ejecución que tarda un código en java en ejecutar alguna sentencia.
long inicio = System.currentTimeMillis(); //Obtiene el tiempo en milisegundos antes de iniciar la siguiente línea de código
ordenarPorBurbuja(A); //Se invoca en este caso el método burbuja para medir su tiempo de ejecución
long fin = System.currentTimeMillis();(); //Obtiene el tiempo en milisegundos después de terminar la anterior línea de código
double tiempo = (double) ((fin - inicio) / 1000); // Al dividir entre 1000 se calcula los segundos que tardo la ejecución
System.out.print("Tiempo de ejecución: " + tiempo); //Muestra los segundos que tardo en ejecutar la sentencia
Evaluación:
Aciertos: 20 puntos por algoritmo codificado y demostración de tiempo de ejecución.
Referencias
Torres, A. C. (2017). Aprenda a Diseñar Algoritmos. Universidad Nacional Abierta y a Distancia.
33
Práctica 5: Uso de Pilas 34
U. Competencia 3: Estructuras de datos lineales y no lineales
Objetivo:
El alumno aplicará el principio de almacenamiento LIFO (Last In, First out) para el uso
de pilas.
Introducción Teórica:
Las estructuras dinámicas son muy útiles en la computación ya que permiten almacenar
información de tamaño variable, recordemos que los arreglos también sirven para
gestionar información, pero tienen la desventaja de ser estáticos, es decir, no crecen
en tiempo de ejecución.
Una pila es una lista de elementos a la cual se puede insertar o eliminar elementos solo
por uno de los extremos. En consecuencia, los elementos de una pila serán eliminados
en orden inverso al que se insertaron; es decir, el último elemento que se mete en la
pila es el primer elemento en salir; a esta estrategia se le denomina LIFO (Last in, First
out).
En la pila se identifican los siguientes elementos:
• la unidad de información recibe el nombre de nodo que consiste en una estructura con
la información de interés y un apuntador que permite acceder al siguiente elemento
• la base de la pila que es el primer nodo y es el que permite el acceso a la estructura
completa
• el tope de la pila que es el último nodo insertado y que será el nodo para eliminar
Las operaciones que se pueden realizar en las pilas son:
35
• Crear la pila
• Insertar la pila también referida como Push
• Eliminar un elemento de la pila también llamada Pop
• Mostrar la información de la pila
• Verificar si la pila está vacía (isEmpty)
//Atributos
private int elemento;
private Nodo siguiente; //Apunta al siguiente nodo
//Constructor
public Nodo(int elemento, Nodo siguiente) {
this.elemento = elemento;
this.siguiente = siguiente;
}
//Métodos
public int getElemento() { return elemento; }
public void setElemento(int elemento) { this.elemento = elemento; }
public Nodo getSiguiente() { return siguiente; }
public void setSiguiente(Nodo siguiente) { this.siguiente = siguiente; }
@Override
public String toString() { return elemento + "\n"; }
}
package ejemplopila;
package ejemplopila;
Nodo inicial= new Nodo(1,null); //se construye el nodo base de la pila, tiene valor 1 y no apunta a otro nodo
Ejercicio
Con base en el código anterior modifica el método main de la clase ejemplo pila para
que sea el usuario el que pueda insertar, visitar los valores de la pila o sacar elementos
de la pila cuando lo decida. Apóyate en la realización de un menú que controle la
interacción del usuario
Evaluación
10 puntos por el proyecto completo
Evidencia
Programa que interactúe con el usuario y sea validado por el profesor
Referencias
Sznajdleder, Pablo Augusto, Java a fondo: estudio del lenguaje y desarrollo de aplicaciones. - 2a ed. Buenos
Aires: Alfaomega Grupo Editor Argentino, 2013, 456 p; ISBN 978-987-1609-36-9
Guardati Buemo Silvia, (2007). “Estructura De Datos Orientada A Objetos, Algoritmos Con C++]”, Pearson
Educación.
Guardati Buemo Silvia. (2016). Estructuras de datos básicas programación orientada a objetos con Java.
Alfaomega Grupo Editor
40
Practica 6: Uso de Colas
U. Competencia 3 Estructuras de datos lineales y no lineales
Objetivo:
El alumno aplicará el principio de almacenamiento FIFO (First In, First out) para el uso
de colas.
Introducción Teórica:
Una cola es una estructura de datos lineal y dinámica que permite gestionar la
información con base en la estrategia FIFO (First In, First out); es decir primer elemento
en entrar será el primer elemento en salir. En la vida cotidiana es fácil identificar las
colas, pues los humanos usamos esta estrategia para considerar a la primera persona
en llegar. Es común ver esta estrategia en los bancos, autobuses y otras oficinas de
atención a clientes.
La cola circular se caracteriza por que el apuntador del final en lugar de apuntar a
null, apunta al frente de la cola, las operaciones encolar y desencolar funcionan de
igual forma que en las demás colas.
Ejemplo
Con base en el paradigma orientado a objetos para implementar una cola se identifican
las siguientes clases:
• Nodo: describe la unidad mínima de información, permite crear nuevos elementos
• Cola: es la clase en la que se definen las operaciones para gestionar la cola
• EjemploCola: es una clase con un método main mediante la cual el usuario podrá
interactuar con el programa
//Contructor
public Nodo(int elemento, Nodo siguiente) {
this.elemento = elemento;
this.siguiente = siguiente;
}
//Métodos
public int getElemento() { return elemento; }
public void setElemento(int elemento) { this.elemento = elemento; }
public Nodo getSiguiente() { return siguiente; }
public void setSiguiente(Nodo siguiente) { this.siguiente = siguiente; }
@Override
public String toString() { return elemento + "\n"; }
}
package ejemplopila;
Evaluación
10 puntos por el programa ejecutado.
Evidencia:
Código de cada clase y la ejecución validada por el profesor
Referencias
Sznajdleder, Pablo Augusto, Java a fondo: estudio del lenguaje y desarrollo de aplicaciones. - 2a ed. Buenos
Aires: Alfaomega Grupo Editor Argentino, 2013, 456 p; ISBN 978-987-1609-36-9
Guardati Buemo Silvia, (2007). “Estructura De Datos Orientada A Objetos, Algoritmos Con C++]”, Pearson
Educación.
Guardati Buemo Silvia. (2016). Estructuras de datos básicas programación orientada a objetos con Java.
Alfaomega Grupo Editor.
Práctica 7: Árboles 46
U. Competencia 1
Objetivo:
El alumno aplicará la metodología para resolver problemas.
Introducción Teórica:
Los árboles representan las estructuras no lineales y dinámicas más importantes en
cómputo.
Un árbol es una estructura jerárquica que se define por:
• Un conjunto de nodos (uno de los cuales se distingue por ser la raíz del árbol)
• Un conjunto de aristas de manera que:
o Cualquier nodo H, a excepción de la raíz, está conectado por medio de
una arista a un único nodo P.
o Un nodo puede tener múltiples hijos.
• Si un nodo tiene algún hijo es un nodo interno, sino es una hoja.
Árbol binario
▪ Dado que un nodo se identifica con el árbol del que es raíz, el recorrido en
profundidad puede seguir el siguiente orden de visita:
Un árbol binario tiene múltiples aplicaciones. Se los puede utilizar para representar una
estructura en la cual es posible tomar decisiones con dos opciones en distintos puntos
de un proceso, para representar la historia de un campeonato de tenis, para representar
un árbol genealógico y para representar expresiones algebraicas construidas con
operadores binarios. Esto sólo para citar algunos de sus múltiples usos.
Ejemplo 50
Para implementar un árbol binario de búsqueda serán necesario al menos tres clases
• El nodo; representa la unidad básica de información; incluye un apuntador para la rama
izquierda y otro apuntador para la rama derecha
• La clase ArbolB, en la que se definen los métodos para recorrer el árbol, insertar y
buscar nodos en la estructura arbórea
• La clase EjArbol en la que se define el método principal para permitir al usuario la
interacción con el programa que gestiona al árbol binario.
public void InsertaBinario (int elem){//define las acciones a verificar al momento de insertar nodo
if(elem < this.elemento){
if (ramaIz == null)
ramaIz = new Nodo(elem);
else
ramaIz.InsertaBinario(elem);
} 51
else{
if (elem > this.elemento){
if (ramaDer == null)
ramaDer = new Nodo(elem);
else
ramaDer.InsertaBinario(elem);
}
} }
//Setters y Getters
public int getElemento() { return elemento; }
public void setElemento(int elemento) { this.elemento = elemento; }
public Nodo getRamaIz() { return ramaIz; }
public void setRamaIz(Nodo ramaIz) { this.ramaIz = ramaIz; }
public Nodo getRamaDer() { return ramaDer; }
public void setRamaDer(Nodo ramaDer) { this.ramaDer = ramaDer; }
@Override
public String toString() {
return "Nodo{" + "elemento=" + elemento + ", ramaIz=" + ramaIz + ", ramaDer=" + ramaDer + '}';
}
}
Clase ArbolB
package ejarbol;
public class ArbolB {
Nodo padre;
Nodo raiz;
Clase EjArbol
package ejarbol;
import java.util.Scanner;
switch(opc) {
case 1:
System.out.println("Dame el número a insertar\n");
int p=leer.nextInt();
A.InsertaNodo(p); break;
case 2: break;
case 3:
System.out.print("El recorrido en Preorden es: ");
A.Preorden (A.raiz);
System.out.println(); break;
case 4:
System.out.print("El recorrido en Inorden es: ");
A.Inorden (A.raiz);
System.out.println(); break;
case 5:
System.out.print("El recorrido en Postorden es: ");
A.PostOrden (A.raiz);
System.out.println(); break;
}//fin switch
}while(opc!=6);//fin do
} }
Ejercicio a realizar
Con base en el código del ejemplo, completa el código para que el usuario pueda buscar
a un elemento y agrega lo necesario para que el usuario pueda recorrer al árbol por
amplitud
Evaluación:
Evidencia:
Programa ejecutándose, código de las clases modificadas y evaluadas por el profesor
Práctica 8: Manejo de archivos y procesamiento de datos. 54
U. Competencia 4: Manejo de archivos.
Duración Estimada: 3 sesiones de 50 minutos
Objetivo: Implementar programas de computadora utilizando persistencia de
objetos, archivos secuenciales de texto y directos, para la solución de problemas
que impliquen el procesamiento de datos.
Introducción Teórica:
REGISTROS
Para la informática, existen distintos tipos de registros, pero en todos los casos hay una
referencia al concepto de almacenar datos o información sobre el proceso o uso de las
computadoras. En específico en lo que se refiere al ámbito de la programación este tipo
de dato está formado por varios elementos en asociación que responden a una misma
estructura. Los registros de programación pueden ser elementales o complejos y
guardan información sobre cómo el software en particular trabajará en cada momento.
En cualquier caso, el empleo de registros tiene el fin de almacenar información es decir
cualquier tipo de datos, ponerla en relación y colocarla al alcance bajo un índice o
sistema de orden que permita su acceso y uso en cualquier momento.
Por lo tanto los registros son el mecanismo que tanto el usuario como el sistema
computacional utilizan para acceder y utilizar toda la información. De lo que resulta ser
un registro se puede derivar distintos conceptos, entre estos están persistencia de
objetos y generación de archivos.
PERSISTENCIA
“Es la propiedad de un objeto por la que su existencia trasciende el tiempo, es decir, el
objeto continúa existiendo después de que su creador deja de existir y/o espacio.” (Lara,
2015).
Visto de otra forma, la persistencia es la acción de mantener la información del objeto
55
de una manera permanente, es decir, guardarla. Pero también debe de poder
recuperarse dicha información para que pueda ser utilizada nuevamente. Por ejemplo,
en lo que se refiere a archivos son las acciones de crear, escribir y leer datos.
La persistencia de objetos en programación orientada a objetos se clasifica en:
• Objetos transitorios: Son aquellos que su tiempo de vida depende del espacio
del proceso que lo creo.
• Objetos persistentes: Son aquellos que su estado es almacenado en un medio
temporal para su posterior reconstrucción y utilización, por lo cual el objeto no
depende del proceso que lo creo.
Archivos
Es un conjunto de bits almacenados en un dispositivo y accesible a través de un camino
de acceso que lo identifica, a este camino se le conoce como pathname. En lo que se
refiere a java, los tipos de archivos o también llamados ficheros se diferencian por las
clases que se usan para representarlos y manipularlos.
Las clases estándar en java que se usan para el tratamiento de archivos están en el
paquete java.io por lo que deben ser importadas para poder manipular ficheros.
Manipulación de archivos.
A continuación, se muestra cómo crear un archivo de texto plano en Java con dos
técnicas diferentes.
Primer método, la clase PrintWriter recibe una cadena con la ruta del archivo o una
instancia de File (en el ejemplo solo se usa directamente la ruta del archivo txt
pathname), el segundo parámetro es el tipo de encoding es usado (UTF-8), que resulta
útil si se necesita guardar texto con caracteres especiales como los utilizados en el
lenguaje español.
El trabajo de escritura se hace con el método println, que permite escribir otros tipos de
datos como enteros, de punto flotante, booleanos y caracteres. ¿Cómo hacerlo?
57
Procedimiento
La práctica a elaborar consistirá en lograr unificar todos los métodos anteriormente
mencionados en un solo código, es decir utilizar las clases PrintWriter, FileWriter,
FileReader, BufferWriter y BufferReader junto con sus respectivos métodos para
escribir y leer datos. El programa debera funcionar de la siguiente manera:
1. Solicitar al usuario que ingrese un texto de al menos 150 palabras que incluya
tanto caracteres como numeros, por ejemplo:
“Reconocido por su legibilidad y simplicidad, Java es uno de los lenguajes de programación
más adoptados: más de 9 millones de desarrolladores lo usan y está presente en 7 mil millones 59
de dispositivos en todo el mundo. Desde 2001 se mantiene en las primeras posiciones…”
El texto que ingrese el usuario deberá ser almacenado en una variable o más de tipo
String.
2. Crear un archivo .txt llamado “mi texto” en el directorio raíz del proyecto java. El archivo
se creara con la clase PrintWriter y el contenido deberá ser lo que el usuario ingreso
como texto.
3. Utilizando las clases FileReader y BufferReader abrir nuevamente el archivo “mi texto”
deberá extraer el texto y almacenarlo en un arreglo de tipo carácter.
4. Crear un método que permita contabilizar la frecuencia de aparición de cada letra y cada
número que aparece en el texto extraído (indistintamente de mayúsculas y minúsculas).
Por ejemplo del texto, “Desde 2001 se mantiene en las primeras posiciones…”
‘A’=3, ‘B’=0, ‘C’=1, hasta, ‘Z’=0, ‘0’=2, ‘1’=1, ‘2’=1, hasta, ‘9’=0
Recuerda que puedes consultar el Anexo de información para tener más datos sobre
las clases del paquete java.io
Evaluación:
Aciertos: 20 puntos por cada punto codificado y funcionamiento correcto.
Evidencia a obtener:
Ejecución del proyecto evaluado por el profesor, mostrando el contendido generado por
los métodos solicitados. Los archivos solicitados deberán contener la información
correcta.
Referencias
Lara, D. (8 de 10 de 2015). styde. Obtenido de https://styde.net/concurrencia-y-
persistencia-en-programacion-orientada-a-objetos/
Torres, A. C. (2017). Aprenda a Diseñar Algoritmos. Universidad Nacional Abierta y a
Distancia.
60
ANEXO