Sunteți pe pagina 1din 70

lica de Chile Pontificia Universidad Cato Escuela de Ingenier a n Departamento de Ciencia de la Computacio IIC1103 Introducci on a la Programaci on

Cap tulo 7: Ordenaci on y B usqueda Resumen te orico


La operaci on de ordenar consisten seleccionar de un conjunto de datos y ordenarlos bajo alg un determinado criterio. Por ejemplo, cada elemento del conjunto de datos de una gu a telef onica tiene un nombre, una direcci on y un n umero de tel efono; la gu a telef onica est a dispuesta en orden alfab etico de nombres; los elementos num ericos se pueden ordenar en orden creciente o decreciente de acuerdo al valor num erico del elemento. En terminolog a de ordenaci on, el elemento por el cual est a ordenado un conjunto de datos (o se est a buscando) se denomina clave. Una colecci on de datos (estructura) puede ser almacenada por ejemplo en un array (vector o tabla). Una estructura se dice que est a ordenada por la clave k si la lista est a en orden ascendente o descendente con respecto a esta clave. La colecci onde datos se dice que est a en orden ascendente si: i < jimplicaquek[i] <= k [j ]. En cambio, est a en orden descendente si: i > jimplicaquek[i] <= k [j ] para todos los elementos de la colecci on. Por ejemplo, para una gu a telef onica, la lista est a clasicada en orden ascendente por el campo clave k, donde k[i] es el nombre del abonado (apellidos, nombre). Un ejempo m as simple de n umeros es la colecci on 4514213245 que se encuentra en orden ascendente y la colecci on 757035161412 en cambio se encuentra en orden descendente.

B usqueda
Los computadores se emplean frecuentemente para almacenar grandes vol umenes de datos. Tener mucha informaci on implica tener dicultades para darle real utilidad. Los algortimos de b usqueda son fundamentales para poder localizar la informaci on relevante en el menor tiempo posible. Los algoritmos de ordenaci on permiten mantener la informaci on ordenada de tal forma que la b usqueda se simplique. Dado un valor X, debolver el ndice del elemento X en el arreglo, en caso de existir. En caso contrario devolver no encontrado (-1). Se supone que en un arreglo no hay entradas duplicadas. Existen varios procedimientos (algoritmos) de b usqueda. Nosotros veremos dos: B usqueda Lineal B usqueda Binaria B usqueda Lineal Consiste en recorrer el arreglo hasta encontrar el elemento buscado (elemento por elemento). Si se llega hasta el u ltimo elemento y a un no se ha encontrado, entonces no se encuentra en la lista.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Declaraci on 1 public int busquedaLineal ( String [] lista , String buscado ) { for ( int i = 0; i < lista.length ; i ++){ if( lista [i].equals( buscado )){ return i;} } return -1; } B usqueda Binaria Restricci on Los elementos de la lista deben estar previamente ordenados. Algoritmo (asumiento orden ascendente) 1. Si el largo de la lista es 0 el programa termina. 2. Se calcula el ndice del elemento central. 3. Se compara el elemento buscado con el elemento central. a ) Si el elemento buscado es mayor al central, se vuelve al paso 1, pero con la sublista [central + 1, largo]. b ) Si el elemento buscado es menor al central, se vuelve al paso 1, pero con la sublista [0, central 1]. c ) Si el elemento buscado es igual al central se retorna el ndice de este. Encontr o el elemento. Declaraci on 2 public int busquedaBinaria ( String [ ] lista , String buscado ) { int inicial = 0; int nal = lista.length - 1; while ( inicial < nal ) { int central = ( inicial + nal )/2; if( buscado.compareTo(lista[central]) > 0){ inicial = central + 1; } else if( buscado.compareTo(lista [central]) < 0){ nal = central - 1; } else{ return central; } } return -1; } Ordenaci on Dado un arreglo con N elementos, ordenarlo en funci on de alguna caracter stica com un entre ellos. Por ejemplo, escribir los valores en orden creciente (o decreciente). Existen una gran cantidad de algoritmos que se diferencian en su rapidez y complejidad. Nosotros veremos dos: Ordenaci on por selecci on. Ordenaci on por burbuja. Ordenaci on por inserci on.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Ordenaci on por selecci on Si quisieramos ordenar ascendentemente: 1. Se busca el menor elemento. 2. Este elemento se cambia con el elemento en el primer lugar de la lista. 3. Se vuelve al paso 1, pero ahora la b usqueda comienza en el siguiente elemento. Se conoce como Selection Sort. Ordenaci on por selecci on Declaraci on 3 public void ordenacionPorSeleccion ( int [] lista ) { for ( int i = 0; i < lista.length -1; i ++) { // Buscamos el menor int menor = i; for ( int j = i + 1; j < lista.length ; j + +){ if( lista [j] < lista [menor]){ menor = j; } // Cambiamos el menor int aux = lista [i]; lista [i] = lista [menor]; lista [menor] = aux ; } } } Ordenaci on por burbuja Si quisieramos ordenar ascendentemente: 1. Se busca el menor elemento. 2. Este elemento se cambia con el elemento en el primer lugar de la lista. 3. Se vuelve al paso 1, pero ahora la b usqueda comienza en el siguiente elemento. Se conoce como Buble Sort. Ordenaci on por burbuja Declaraci on 4 public void ordenacionPorBurbuja ( int [] lista ) { for ( int i = 1; i < lista . length ; i ++) { for ( int j = i - 1; j 0; j - -) { if( lista [j +1] < lista [j]) { // Intercambio int aux = lista [j +1]; lista [j +1] = lista [j]; lista [j] = aux ; } else { break; } } } } IIC1103 Cap tulo 7: Ordenaci on y B usqueda 3

Ordenaci on por inserci on 1. Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado. 2. Despu es, cuando hay k elementos ordenados de menor a mayor, se toma el elemento k+1 y se compara con todos los elementos ya ordenados 3. deteni endose cuando se encuentra un elemento menor (todos los elementos mayores han sido desplazados una posici on a la derecha). 4. En este punto se inserta el elemento k+1 debiendo desplazarse los dem as elementos. Se conoce como Insertion Sort. Declaraci on 5 public void insertSort (int[] v) { for (int i=1; i < v.length; i + +) { int aux = v[i]; int j; for (j=i-1; j>=0 && v[j] > aux; j - -){ v[j+1] = v[j];} v[j+1] = aux; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Ejemplos
Problema 1: Patentes
Enunciado Las antiguas patentes (de autom oviles), por ejemplo PL7812, est an compuestas por un string de dos caracteres, en el ejemplo PL, y por un n umero entero de cuatro d gitos, en el ejemplo 7812. Suponga que exista una clase Patente y otra TablaDePatentes de la siguiente forma:
public class Patente { private String letras ; private int numero ; public Patente () {} public String obtLetras () { return letras ; } public int obtNumero () { return numero ; } } public class T ab la De P at en t es { private String [] tabla ; public Tabl aD eP a te nt es () { tabla = new String [9999]; } public boolean buscar ( Patente patente ) {} otros metodos }

La idea es que TablaDePatentes almacena en el atributo tabla todas las patentes autorizadas a estacionarse en el campus San Joaqu n. En particular, si la patente PL7812 est a autorizada, entonces tabla[7812] = PL, y si la patente JK2345 est a autorizada, entonces tabla[2345] = JK. Adem as, si dos o m as patentes autorizadas tienen el mismo n umero, entonces sus pares de letras aparecen consecutivamente en el string correspondiente de tabla. Por ejemplo, si las patentes PL7812 y MB7812 est an ambas autorizadas, entonces tabla[7812] = PLMB; y si las patentes JK2345, RC2345 y DW2345 est an todas autorizadas, entonces tabla[2345] = JKRCDW. Escriba el m etodo buscar de la clase TablaDePatentes, que busca r apidamente la Patente patente en el atributo tabla, y devuelve true (verdadero) si patente est a en tabla, y false (falso) en caso contrario. Criterios de soluci on Lo primero que tenemos que hacer es declarar el m etodo como nos indican en el enunciado. Luego, con los m etodos de la clase Patente, obtenemos las letras y los n umeros que la componen. Con el n umero de la patente obtenemos lo almacenado en el arreglo y luego debemos recorrer este String obteniendo Substring de largo 2 e ir comparando cada substring con las letras de la patente a buscar. Si coincide con alguno retornamos true, de lo contrario retornamos false. Posible soluci on
public boolean buscar ( Patente patente ) { int num = patente . obtNumero (); String letras = patente . obtLetras (); String validas = tabla [ num ]; if ( validas != null ){ int largo = validas . length (); int k = 1; while ( k < largo ) { if ( letras . equals ( validas . substring ( k - 1 , k + 1))) return true ; k = k + 2; } } return false ; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Problema 2: Distancia entre puntos


Enunciado Implemente un programa que busque la mayor distancia entre un grupo de puntos e identique los puntos que est an a la mayor distancia encontrada. Para esto pida al usuario el n umero de puntos a utilizar y luego cree cada uno de los puntos. Para hacerle m as f acil la implementaci on cuenta con la clase Punto mostrada a continuaci on.
import iic1103Packa ge .*; public class Punto { private double x ; private double y ; public Punto ( double x , double y ) { this . x = x ; this . y = y ; } public Punto () { double r ; r = Aleatorio . real (0 , 1000); this . x = r ; r = Aleatorio . real (0 , 1000); this . y = r ; } public double getX () { return x ; } public double getY () { return y ; } public double distancia ( Punto p ) { return ( Math . sqrt (( this . x - p . getX ()) * ( this . x - p . getX ()) + ( this . y - p . getY ()) * ( this . y - p . getY ()))); } }

Luego de la ejecuci on su programa debe mostrar un mensaje como el siguiente: .\\La mayor distancia en el conjunto de puntos es 1058.91295913645 e involucra al punto 0: (10.920578500052901,15.64305239454644) y al punto 4: (644.0265655345464,864.4501354282548) Criterios de soluci on Antes de buscar la distancia debemos crear los puntos necesarios. Para eso pedimos al usuario la cantidad de puntos a utilizar y luego con un ciclo creamos cada uno de los puntos. Luego de que tenemos creados los puntos debemos recorrerlos y calcular la distancia entre cada uno de ellos. Para ello podemos utilizar un doble ciclo que recorra cada punto y luego lo compare con todos los puntos restantes. Utilizamos variables que almacenen el valor de la distancia m axima y la posici on en el arreglo de los puntos involucrados. Luego dentro del ciclo calculamos la distancia entre los puntos y la comparamos con la distancia m axima encontrada hasta el momento, actualizando las variables cuando corresponda.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Posible soluci on
import iic1103Packa ge .*; public class Main { public static void main ( String [] args ) { int n_puntos , i , j , p1 = 0 , p2 = 0; double dist_max = 0; Punto [] puntos ; n_puntos = Usuario . entero ( " Cuantos puntos usara para el ejercicio ? " ); puntos = new Punto [ n_puntos ]; for ( i = 0; i < n_puntos ; i ++) { puntos [ i ] = new Punto (); } for ( i = 0; i < ( n_puntos - 1); i ++) { for ( j = i + 1; j < n_puntos ; j ++) { if ( puntos [ i ]. distancia ( puntos [ j ]) > dist_max ) { dist_max = puntos [ i ]. distancia ( puntos [ j ]); p1 = i ; p2 = j ; } } } Usuario . mens ajeConso la ( " La mayor distancia en el conjunto de puntos es " + dist_max + " e involucra al punto " + p1 + " : ( " + puntos [ p1 ]. getX () + " ," + puntos [ p1 ]. getY () + " ) y al punto " + p2 + " : ( " + puntos [ p2 ]. getX () + " ," + puntos [ p2 ]. getY () + " ) " ); } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Problema 3: Diccionario
Enunciado En el desarrollo de un editor de texto (como Word), se necesita incorporar un diccionario de manera de poder corregir la ortograf a del documento. Para esto, se le pide implementar la clase Diccionario que pueda construirse con un tama no entero positivo dado, que ser a la capacidad m axima del diccionario. Se le pide implementar los m etodos: AgregarPalabra(String s) agrega s al diccionario si no existe ya en este y si es que queda espacio para agregarla. String ConsultarPalabra(String s) busca s en el diccionario. Si la encuentra, le avisa al usuario con un mensaje. Si no la encuentra, retorna la palabra que produjo el menor valor (en valor absoluto) como resultado de la comparaci on usando el m etodo compareTo. Criterios de soluci on Para implementar el Diccionario lo m as l ogico es utilizar un arreglo de String para representar las palabras que lo componen. Luego debemos implementar los m etodos que nos piden. M etodo ConsultarPalabra: Utilizamos una variable para almacenar la palabra a menor distancia de la buscada. Recorremos todo el arreglo y revisamos la distancia de la siguiente palabra a la palabra buscada utilizando el m etodo compareTo. Si la distancia es menor que la menor distancia encontrada hasta el momento actualizamos la variable. Finalmente revisamos si la palabra encontrada es igual a la buscada, si es as mostramos un mensaje indicando que encontramos la palabra. M etodo AgregarPalabra: Revisamos que el arreglo no est e lleno y que la palabra ya no est e en el diccionario. Para esto u ltimo llamamos al m etodo ConsultarPalabra y revisamos si la palabra retornada por este m etodo es igual a la palabra que queremos agregar. Si no es as agregamos el string al arreglo en la posici on que corresponde. Posible soluci on
import iic1103Packa ge .*; public class Diccionario { private String [] palabras ; private int p roximaP alabra ; public Diccionario ( int maxPalabras ) { palabras = new String [ maxPalabras ]; proximaPala bra = 0; } public void Ag regarPa labra ( String s ) { // Revisamos que se puedan insertar mas palabras y que la palabra no se // encuentre en el arreglo if ( proximaP alabra < palabras . length && ! C o n su l t a r P a l a b r a ( s ). equals ( s )) { palabras [ proxim aPalabra ] = s ; proximaPala bra ++; } } public String C o n su l t a r P a l a b r a ( String s ) { // Buscamos la palabra que mas se acerque a la dada String palabraMenor = palabras [0]; for ( int i = 1; i < prox imaPala bra ; i ++) { if ( Math . abs ( palabras [ i ]. compareTo ( s )) < Math . abs ( palabraMenor . compareTo ( s ))) { palabraMenor = palabras [ i ]; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

// Revisamos si la palabra encontrada es la misma que buscbamos if ( palabraMenor . equals ( s )) { Usuario . mensaje ( " Se encontro la palabra . " ); } return palabraMenor ; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

Problema 4: Analizar c odigo


Enunciado Para el siguiente c odigo 1. Describa, en castellano, que representa la Clase A 2. Describa, en forma clara y precisa, qu e hacen los m etodos m1 y m2
public class ClaseB { private int x1 , x2 , x3 ; private String s ; public ClaseB ( String s , int x1 , int x2 , int x3 ) { this . s = s ; this . x1 = x1 ; this . x2 = x2 ; this . x3 = x3 ; } String getS () { return s ; } int getX1 () { return x1 ; } int getX2 () { return x2 ; } int getX3 () { return x3 ; } } public class ClaseA { private ClaseB [] Arr ; private int tam ; ClaseA ( String s , int t ) { Arr = new ClaseB [ t ]; tam = 0; } public void m1 ( ClaseB b ) { Arr [ tam ++] = b ; } public void m2 () { int i , k ; for ( k = Arr . length - 1; k > 0; k - -) { for ( i = 0; i < k ; i ++) { ClaseB aux ; if ( Arr [ i ]. getS (). compareTo ( Arr [ i + 1]. getS ()) > 0) { aux = Arr [ i ]; Arr [ i ] = Arr [ i + 1]; Arr [ i + 1] = aux ; } } } } }

Criterios de soluci on En este tipo de problemas es buena opci on escribir a un lado una tabla con las variables, arreglos y objetos, e ir anotando los cambios l nea a l nea, realizando una especie de debug manual. Se debe ser bastante

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

10

sistem atico para no equivocarse, y cuidar interpretar correctamente los cambios en las variables, arreglos y en los objetos. Entendiendo bien cada paso de los m etodos se puede interpretar qu e est an calculando. Posible soluci on 1. ClaseA es una lista/conjunto/colecci on de elementos de ClaseB. 2. m1 agrega un elemento a la lista m2 ordena la lista por el atributo String de ClaseB y en forma ascendente.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

11

Problema 5: Ordenando Strings


Enunciado Usted recibe una matriz con el siguiente contenido: c b a a z i z b a Donde cada car acter es un char. Debe crear un programa que ordene alfab eticamente esta matriz, primero las las y despu es, sin cambiar las las, las columnas, de tal manera que quede as : a b c a b z a i z Aunque este problema se puede resolver de manera sucia, resu elvalo pensando que este programa debe ser aplicable a cualquier matriz de 3x3. Criterios de soluci on Lo importante aqu es darse cuenta de que cada la de una matriz se puede tratar como un arreglo unidimensional. Para hacer esto ocupamos matriz[i][j] dejando el i est atico. Con esto vamos a ir obteniendo los valores de nuestras las. Luego para ordenarlas, se revisa uno por uno los caracteres y se le compara con todos los otros caracteres de la misma la. En caso de que sea mayor, se pone a la derecha del car acter revisado. Luego es cosa de hacer lo mismo pero ahora para las columnas.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

12

Posible soluci on
public class Ordenar { public static boolean sonIguales ( char [] palabra1 , char [] palabra2 , int tamano ) { for ( int i = 0; i < tamano ; i ++) { if ( palabra1 [ i ] != palabra2 [ i ]) { // vemos letra por letra return false ; // revisando que sean iguales } } return true ; } public static void main ( String [] args ) { int tamanoMatriz = 3; char [][] matriz = new char [ tamanoMatriz ][]; char [] fila1 = { c , b , a }; char [] fila2 = { a , z , i }; char [] fila3 = { z , b , a }; matriz [0] = fila1 ; // inicializamos la matriz con las filas matriz [1] = fila2 ; matriz [2] = fila3 ; for ( int i = 0; i < tamanoMatriz ; i ++) { // en este for comparamos cada letra de cada fila for ( int j = 0; j < tamanoMatriz ; j ++) { for ( int k = 0; k < tamanoMatriz ; k ++) { char auxiliar ; if ( matriz [ i ][ j ] < matriz [ i ][ k ]) { // si es que la letra es menor se va para la derecha auxiliar = matriz [ i ][ j ]; matriz [ i ][ j ] = matriz [ i ][ k ]; matriz [ i ][ k ] = auxiliar ; } } } } for ( int j = 0; j < tamanoMatriz ; j ++) { // en este for comparamos cada fila con cada fila for ( int k = 0; k < tamanoMatriz ; k ++) { int i = 0; if (! sonIguales ( matriz [ j ] , matriz [ k ] , tamanoMatriz )) { // si son iguales no hacemos nada while ( matriz [ j ][ i ] == matriz [ k ][ i ]) { // esperamos a encontrar una letra distinta // ( por ejemplo cuando comparamos " abc " con " abz ") i ++; } char [] auxiliar ; if ( matriz [ j ][ i ] < matriz [ k ][ i ]) { // si la letra es menor cambiamos la palabra auxiliar = matriz [ j ]; matriz [ j ] = matriz [ k ]; matriz [ k ] = auxiliar ; } } } } for ( int i = 0; i < tamanoMatriz ; i ++) { // imprimimos for ( int j = 0; j < tamanoMatriz ; j ++) { System . out . print ( matriz [ i ][ j ]); } System . out . println ( " " ); } } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

13

Problema 6: Estad stica de orden


Enunciado Un n umero x es la i- esima estad stica de orden de un vector A si y s olo si x es el i- esimo n umero m as peque no del conjunto. As , si A = (1, 2, 4, 1), la primera (1- esima) estad stica de orden es 1, la segunda (2- esima) estad stica de orden es 1 y la tercera (3- esima) estad stica de orden es 2. La operaci on matricial se dene entre una matriz M de vector de n elementos. La siguiente igualdad: a11 a11 . . . a1m a21 a21 . . . a2m . . . . . . . . . . . . an1 an2 ... anm se cumple si y s olo si el valor ui es la vi - esima Por ejemplo, la siguiente igualdad: 1 2 4 5 7 8 4 6 9 n m y un vector v de n elementos, y retorna un u1 v1 v2 u2 . = . , . . . . vn un

estad stica de orden de (ai1 , ai2 , . . . , aim ). 3 4 2 = 5 , 1 7

se cumple porque 4 es la tercera estad stica de orden de (1, 2, 4), 5 es la segunda estad stica de orden de (4, 5, 6) y 7 es la primera estad stica de orden de (7, 8, 9). Escriba un m etodo con el encabezado: public int [] estadistica (int[][] M, int [] V) que recibe una matriz M y un vector Vrepresentado como un arreglo de enterosy retorna el resultado de M V en un arreglo. Puede suponer que M y V siempre tendr an dimensiones adecuadas y que los n umeros en V no piden estad sticas fuera de rango. Criterios de soluci on Para encontrar la i- esima estad stica de orden de un vector lo que tenemos que hacer es ordenar el arreglo de menor a mayor. Para esto podemos utilizar cualquier c odigo de ordenaci on, como por ejemplo selection sort. Con el arreglo ya ordenado simplemente buscamos en la posici on i-1 y tenemos la i- esima estad stica de orden. Luego para implementar el m etodo que nos piden tenemos que crear un nuevo arreglo para retornar de tama no adecuado y luego, con un ciclo, obtener la i esima estad stica de orden de la la de la matriz correspondiente seg un el valor en el arreglo recibido como par ametro.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

14

Posible soluci on
public static int iesima ( int [] A , int i ) { // aqui va cualquier algoritmo de ordenacion // en este ejemplo , ocupamos selection sort for ( int j = A . length - 1; j >= 2; j - -) { int max ; max = 0; for ( int k = 1; k <= j ; k ++) { if ( A [ k ] > A [ max ]) max = k ; } int aux ; aux = A [ max ]; A [ max ] = A [ j ]; A [ j ] = aux ; } return A [ i - 1]; } public static int [] estadistica ( int [][] M , int [] V ) { int i ; int [] U = new int [ M . length ]; for ( i = 0; i < M . length ; i ++) { U [ i ] = iesima ( M [ i ] , V [ i ]); } return U ; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

15

Problema 7: Cadena Creciente


Enunciado Dados un arreglo lista con n elementos y un par de ndices i, j tal que 0 i j < n, el arreglo formado por los elementos lista[i], lista[i + 1], lista[i + 2], . . ., lista[j ] se dice una cadena creciente si: lista[i] < lista[i + 1] < lista[i + 2] < < lista[j ]. Adem as, se dice que el largo de esta cadena es el n umero de elementos en ella, vale decir, j i + 1. En esta pregunta, usted debe implementar un m etodo con encabezado: public int[] encontrarCadenaCreciente(int[] lista) que recibe como entrada un arreglo de n umeros enteros, y retorna un arreglo conteniendo la cadena creciente m as larga en el arreglo de entrada. Por ejemplo, si lista es un arreglo formado por los 12 elementos {2, 3, 5, 4, 8, 18, 0, 2, 3, 4, 4, 6}, entonces el arreglo de salida de encontrarCadenaCreciente debe ser el arreglo de 4 elementos {0, 2, 3, 4}, ya que esta es la cadena creciente m as larga en lista. Nota: Si existen varias cadenas crecientes en lista que tienen largo m aximo, su procedimiento debe retorna alguna de ellas. Criterios de soluci on Posible soluci on
public int [] e n c o n t r a r C a d e n a C r e c i e n t e ( int [] lista ) { int i , aux , inicio , largo ; boolean entrar ; i = 0; aux = 0; inicio = 0; largo = 0; while ( i < lista . length ) { entrar = true ; while ( entrar ) { if ( i == ( lista . length - 1)) { entrar = false ; } else if ( lista [ i ] < lista [ i + 1]) { i ++; } else { entrar = false ; } } if (( i - aux ) + 1 > largo ) { largo = ( i - aux ) + 1; inicio = aux ; } i ++; aux = i ; } int [] cadena = new int [ largo ]; for ( i = 0; i < largo ; i ++) { cadena [ i ] = lista [ inicio + i ]; } return cadena ; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

16

Problema 8: OrdDup
Enunciado Para representar listas de n umeros enteros con repeticiones se ha decidido utilizar la siguiente estructura. Un arreglo de largo 2n tiene almacenados en la posici on 2k (0 = k n) un n umero de la lista y en 2k + 1 el n umero de veces que este n umero aparece repetido. Por ejemplo, el arreglo 2, 3, 5, 4 representa a la lista que tiene el n umero 2 repetido 3 veces y el n umero 5 repetido 4 veces. En esta pregunta usted debe implementar el m etodo: public boolean OrdDup(int[] arreglo) el cual recibe como par ametro una lista arreglo en el formato descrito arriba, y ordena esta lista de manera ascendente. Por ejemplo, si arreglo = 3, 6, 2, 5, -1, 9, 7, 3, entonces despu es de invocar al m etodo se debe tener que arreglo = -1, 9, 2, 5, 3, 6, 7, 3, que corresponde al orden ascendente de los n umeros 3, 2, -1, 7 que conten a la lista original, junto con los n umeros correspondientes de repeticiones. N otese que OrdDup retorna un valor booleano. Como no todo arreglo representa una lista con repeticiones, OrdDup retorna true si arreglo corresponde a una lista con repeticiones, y false en caso contrario. En el primer caso, el m etodo ordena arreglo, mientras que en el segundo lo deja intacto. Importante: Para resolver esta pregunta puede suponer que arreglo no tiene n umeros repetidos en las componentes que representan los n umeros de la lista. Por ejemplo, arreglo puede ser 12, 3, 5, 7 y no puede ser 12, 3, 5, 4, 12, 1 ya que el 12 aparece dos veces. N otese que arreglo puede ser 12, 3, 5, 3 ya que en este caso no hay repeticiones entre los n umeros de la lista (12 y 5). Dado lo anterior, para vericar si un arreglo almacena una lista con repeticiones hay que chequear dos condiciones: el largo del arreglo es par, y el n umero de repeticiones de cada n umero es mayor que 0. As , por ejemplo, para los arreglos 2, 3, 5, 2, -1, 3, 8 y 2, 4, 1, 0, el m etodo OrdDup debe retornar false. Criterios de soluci on Posible soluci on
public boolean OrdDup ( int [] arreglo ) { if ( arreglo . length % 2 != 0) { return ( false ); } else { int i , k , aux , cant ; for ( i = 0; i < arreglo . length / 2; i ++) if ( arreglo [2 * i + 1] <= 0) { return ( false ); } } for ( i = 1; i < arreglo . length / 2; i ++) aux = arreglo [2 * i ]; cant = arreglo [2 * i + 1]; k = i - 1; while ( k >= 0 && arreglo [2 * k ] > aux ) arreglo [2 * k + 2] = arreglo [2 * k ]; arreglo [2 * k + 3] = arreglo [2 * k + k = k - 1; } arreglo [2 * k + 2] = aux ; arreglo [2 * k + 3] = cant ; } return ( true ); } }

{ 1];

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

17

Problema 9: Lista de Amigos


Enunciado Se ha creado un programa para ayudarle a manejar una lista de contactos. El programa tiene las clases DatosAmigo y Contactos que se describen a continuaci on. Los m etodos que aparecen a continuaci on ya han sido denidos e implementados, no es necesario que conozca la implementaci on, pero s c omo utilizarlos. Clase DatosAmigo Almacena la informaci on sobre un amigo: nombre, apellido, celular y email. M etodos public DatosAmigo(String no, String ap, int ce, String em) : Constructor de la clase; recibe el nombre, apellido, celular y email de un amigo. public String getNombre(): Retorna el nombre del amigo. public int getCelular(): Retorna el celular del amigo. Clase Contactos Almacena la informaci on de una lista de contactos. Atributos private DatosAmigo[] amigos: Lista de contactos, es un arreglo que almacena los datos de los amigos. M etodos public Contactos(): Constructor de la clase. public void AgregarAmigo(DatosAmigo da): Permite agregar la informaci on de un amigo a la lista de contactos; autom aticamente agranda el arreglo para contener al nuevo amigo. Se le pide que implemente los siguientes m etodos de la clase Contactos: public void MostrarEmailPorNombre(String nombre): Muestra en la consola el nombre, apellido y email de todos los amigos cuyo nombre (independiente de min usculas o may usculas) es igual al que se recibe como par ametro. public DatosAmigo[] RecordarEmail(String trozoEmail): Retorna un arreglo de objetos del tipo DatosAmigo con todos los amigos cuyo email comienza con el trozo de email que se recibe como par ametro. Puede suponer que todos los e-mails se escriben en min usculas. public String getApellido(): Retorna el apellido del amigo. public String getEmail(): Retorna el e-mail del amigo.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

18

Para ayudarle a entender el funcionamiento deseado, se ilustra a continuaci on el funcionamiento de estos m etodos:
public static void main ( String [] args ) { Contactos lista ; lista = new Contactos (); DatosAmigo amigo ; amigo = new DatosAmigo ( " Marcos " , " Sepulveda " , 1234 , " marcos@ing . puc . cl " ); lista . AgregarAmigo ( amigo ); amigo = new DatosAmigo ( " Karen " , " Palma " , 2345 , " kpalma@ing . puc . cl " ); lista . AgregarAmigo ( amigo ); amigo = new DatosAmigo ( " Marcelo " , " Arenas " , 3456 , " marenas@ing . puc . cl " ); lista . AgregarAmigo ( amigo ); amigo = new DatosAmigo ( " Rosa " , " Alarcon " , 4567 , " ralarcon@ing . puc . cl " ); lista . AgregarAmigo ( amigo ); amigo = new DatosAmigo ( " Matias " , " Recabarren " , 5678 , " mat . reca@gmail . com " ); lista . AgregarAmigo ( amigo ); lista . M o s t r a r E m a i l P o r N o m b r e ( " Marcos " ); DatosAmigo [] listado = lista . RecordarEmail ( " mar " ); Usuario . mens ajeConso la ( " Listados de emails " ); for ( int i = 0; i < listado . length ; i ++) { Usuario . mensa jeConso la ( listado [ i ]. getEmail ()); } }

. Salida en Consola
Emails por nombre - Marcos Marcos Sepulveda marcos@ing . puc . cl Listados de emails marcos@ing . puc . cl marenas@ing . puc . cl

Criterios de soluci on Posible soluci on


public void M o s t r a r E m a i l P o r N o m b r e ( String nombre ) { Usuario . mens ajeConso la ( " Emails por nombre - " + nombre ); for ( int i = 0; i < this . amigos . length ; i ++) { DatosAmigo am = this . amigos [ i ]; if ( am . getNombre (). e q ua l s I g n o r e C a s e ( nombre )) { Usuario . mensa jeConso la ( am . getNombre () + " \ t " + am . getApellido () + " \ t " + am . getEmail ()); } } } public DatosAmigo [] RecordarEmail ( String trozoEmail ) { DatosAmigo [] nuevo ; int nCoinc idencias = 0; for ( int i = 0; i < this . amigos . length ; i ++) { DatosAmigo am = this . amigos [ i ]; if ( am . getEmail (). length () >= trozoEmail . length ()) { String trozo = am . getEmail (). substring (0 , trozoEmail . length ()); if ( trozo . e q u a l s I gn o r e C a s e ( trozoEmail )) { nCoi ncidenci as ++; } } } nuevo = new DatosAmigo [ nCoinci dencias ]; int j = 0; for ( int i = 0; i < this . amigos . length ; i ++) { DatosAmigo am = this . amigos [ i ]; if ( am . getEmail (). length () >= trozoEmail . length ()) { String trozo = am . getEmail (). substring (0 , trozoEmail . length ()); if ( trozo . e q u a l s I gn o r e C a s e ( trozoEmail )) { nuevo [ j ] = am ; j ++; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

19

} } return nuevo ; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

20

Problema 10: M etodo desconocido


Enunciado Para el siguiente c odigo responda las siguientes preguntas: 1. Qu e muestra el programa en la consola? 2. Qu e hace metodo1 y c omo lo hace?
public class Principal { public static void main ( String [] args ) { int [] a = { 10 , 25 , 17 , 7 , 15 , 6 , 9 , 12 }; metodo2 ( a ); metodo1 ( a ); metodo2 ( a ); } private static void metodo1 ( int [] a ) { boolean b = false ; int c = 2; int d = a . length ; int e = 0 , f = 0; while ( b || ( d > 1)) { d = d / c; if ( d == 0) { d = 1; } else if ( d == 9 || d == 10) { d = 11; } b = false ; int top = a . length - d ; for ( int i = 0; i < top ; i ++) { int j = i + d ; f ++; if ( a [ i ] > a [ j ]) { int t = a [ i ]; a [ i ] = a [ j ]; a[j] = t; b = true ; e ++; } } } Usuario . mens ajeConso la ( f ); Usuario . mens ajeConso la ( e ); } private static void metodo2 ( int [] a ) { String s = " " ; for ( int i = 0; i < a . length ; i ++) { s += a [ i ] + " " ; } Usuario . mens ajeConso la ( s ); } }

Criterios de soluci on Posible soluci on 1.


10 25 17 7 15 6 9 12 31 8 6 7 9 10 12 15 17 25

2. El metodo1 ordena el arreglo recibido, para lo cual dene un salto (la variable d), y luego compara cada elemento con el que se encuentra a d de distancia de el en el arreglo. Luego, va disminuyendo

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

21

d, cuidando que no sea menor que 1. El algoritmo termina cuando d es 1 y se compararon todos los elementos del arreglo con esa distancia sin realizar ninguna permutaci on.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

22

Problema 11: Tama no optimo


Enunciado En el proceso productivo de una f abrica de envases de lata, se requiere alimentar una m aquina cortadora con la plancha de lata de tama no optimo, de modo de minimizar las p erdidas. Una vez denido el tama no optimo, se ingresa a la m aquina el tama no de la plancha de lata (largo y ancho) y el radio de cada c rculo, con lo cual la m aquina cortar a la mayor cantidad de c rculos tal como se muestra en la gura a continuaci on.

Considerando que existen N tipos de planchas con medidas distintas (largo y ancho), se solicita crear un programa que determine cu al es la medida optima de la plancha con que se debe alimentar la cortadora, para minimizar el material perdido. El programa debe calcular para cada tipo de plancha, la cantidad de c rculos, el area perdida y luego debe obtener un listado ordenado de menor a mayor material perdido, indicando las medidas de cada plancha, la cantidad de c rculos y la supercie perdida. Datos entrada: N: cantidad de tipos de planchas Largo y ancho de cada uno de los N tipos de plancha en mil metros. Radio de corte del c rculo requerido en mil metros Datos salida: Listado de todas las planchas ingresada ordenado de menor a mayor supercie perdida indicando para cada una: Largo y Ancho de la plancha Cantidad de c rculos obtenidos. Supercie perdida en mil metros cuadrados La cantidad de c rculos en la supercie es la siguiente: Circulos = (Ancho/((2 radio) + 0,5)) (Largo/((2 radio) + 0,5)) Obs. Se debe considerar que la m aquina de corte necesita 5 mil metros como m nimo entre cada c rculo para efectuar el corte. Nota: Los datos de entrada deben ser pedidos al usuario y la informaci on de salida debe aparecer en la consola. Criterios de soluci on Posible soluci on

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

23

import iic1103Packa ge .*; public class Principal { public static void main ( String [] args ) { // Declaraciones iniciales y datos int n , radio ; n = Usuario . entero ( " Ingrese tipos de planchas : " ); int [][] m = new int [ n ][4]; radio = Usuario . entero ( " Ingrese radio : " ); // llenar matriz de medidas for ( int i = 0; i < n ; i ++) { m [ i ][0] = Usuario . entero ( " Ingrese largo plancha : " ); m [ i ][1] = Usuario . entero ( " Ingrese ancho plancha : " ); } // calculo cantidad circulos / plancha y superficie perdida for ( int i = 0; i < n ; i ++) { m [ i ][2] = m [ i ][0] / (2 * radio + 10) * m [ i ][1] / (2 * radio + 10); m [ i ][3] = ( int ) ( m [ i ][0] * m [ i ][1] - Math . PI * Math . pow ( radio , 2) * m [ i ][2]); } // ordernar el arreglo de menor a mayor material perdido int aux ; for ( int i = 0; i < n - 1; i ++) { for ( int j = i + 1; j < n ; j ++) { if ( m [ i ][3] > m [ j ][3]) { aux = m [ i ][3]; m [ i ][3] = m [ j ][3]; m [ j ][3] = aux ; aux = m [ i ][2]; m [ i ][2] = m [ j ][2]; m [ j ][2] = aux ; aux = m [ i ][1]; m [ i ][1] = m [ j ][1]; m [ j ][1] = aux ; aux = m [ i ][0]; m [ i ][0] = m [ j ][0]; m [ j ][0] = aux ; } } } // Imprimir los datos ordenados Usuario . mensaje ( " Largo Ancho circulos for ( int i = 0; i < n ; i ++) { for ( int j = 0; j < 4; j ++) { Usuario . mensaje ( m [ i ][ j ]); } } } } Superf " );

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

24

Problema 12: B usqueda Matriz Irregular


Enunciado Una matriz se dice irregular si algunas de sus las no tienen el mismo n umero de columnas. Por ejemplo, la siguiente es una matriz irregular:

Las matrices irregulares de n umeros no negativos pueden ser almacenadas en arreglos de la siguiente forma. Dada una matriz M, cada la de M es almacenada en posiciones contiguas del arreglo. Estas las son almacenadas de manera ordenada, es decir, la la i- esima de M es almacenada en el arreglo antes que la la j- esima de M si i j. Adem as, el n umero -1 es usado para indicar el n de una la. Por ejemplo, la matriz mostrada arriba es almacenada en el siguiente arreglo:

En esta pregunta usted deber a implementar un m etodo con encabezado public int valor(int[] M, int i, int j) que recibe como par ametros una matriz irregular de n umeros no negativos almacenados en el arreglo M (como se indica arriba), y las posiciones i, j, y retorna el n umero que est a en la la i y columna j de M (recuerde que la primera la de una matriz es la n umero 0, al igual que para las columnas). Por ejemplo, si M es el arreglo mostrado arriba, entonces la llamada: valor(M, 2, 2) debe entregar como resultado 10, ya que el elemento en la la 2 y columna 2 de M es 10. Importante: El m etodo valor debe retornar -1 si el par ametro i o el par ametro j est an fuera de los rangos de la matriz M. Por ejemplo, si M es la matriz mostrada arriba, las invocaciones valor(M, 3, 0), valor(M, -1, 0), valor(M, 2, 4) deben retornar -1. Adem as, su implementaci on debe manejar correctamente el caso en que una la no tiene elementos (lo cual aparece en el arreglo como dos n umeros -1 contiguos). Criterios de soluci on Posible soluci on
public int numero_filas ( int [] M ) { int i , num ; num = 0; for ( i = 0; i < M . length ; i ++) if ( M [ i ] == -1) num ++; return num ; } public int valor ( int [] M , int i , int j ) { if ( i < 0 || i >= numero_filas ( M ) || j < 0) return -1; else { int fila , columna , pos ; fila = 0; pos = 0; while ( fila < i ) { if ( M [ pos ] == -1)

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

25

fila ++; pos ++; } columna = 0; while ( columna < j && M [ pos ] != -1) { columna ++; pos ++; } if ( M [ pos ] == -1) return -1; else return M [ pos ]; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

26

Problema 13: Combate Naval


Enunciado Usted deber a implementar una versi on simplicada del conocido juego Combate Naval. El juego consta de un tablero bidimensional sobre el cual se disponen estrat egicamente barcos de combate, y el objetivo es que su rival no logre adivinar las posiciones de sus barcos, o bien, que no lo haga antes de que usted adivine las posiciones de los barcos de el. Por tratarse de una versi on simplicada, la implementaci on que Usted haga resultar a en un prototipo que no es completamente funcional. Sin embargo, su programa deber a permitir agregar barcos a su tablero, quitarlos del mismo, mostrar informaci on relevante que d e cuenta del estado de una contienda, recibir y procesar correctamente un ataque, entre otras cosas. Para la realizaci on del laboratorio usted cuenta con la clase Principal, con su respectivo m etodo main, y la clase Oponente, que representa al rival de esta versi on simplicada del juego, ambas ya implementadas. Observe que esta clase tiene como u nica nalidad proporcionarle la posibilidad de probar algunos de los m etodos que Usted deber a implementar, mediante la generaci on de ataques de naturaleza aleatoria.
import iic1103Packa ge .*; public class Oponente { public Oponente () { } public int [] atacar ( int largoMar , int anchoMar ) { int [] c oo r d e n a d a s A t a q u e = new int [2]; co ord enad a s A t a q u e [0] = Aleatorio . entero (0 , largoMar ); co ord enad a s A t a q u e [1] = Aleatorio . entero (0 , anchoMar ); return co o r d e n a d a s A t a q u e ; } } import iic1103Packa ge .*; public class Principal { public static void main ( String [] args ) { Usuario . mensaje ( " Bienvenido a \" Combate Naval \" version 0.0.0.1! " ); int largoTablero = Usuario . entero ( " Ingrese el largo del Tablero de Juego : " ); int anchoTablero = Usuario . entero ( " Ingrese el ancho del Tablero de Juego : " ); int maxBarcos = Usuario . entero ( " Ingrese la cantidad maxima de barcos " + " que se puede agregar al Tablero : " ); while ( maxBarcos *2 > largoTablero || maxBarcos *2 > anchoTablero ) { Usuario . mensaje ( " La cantidad de barcos no puede ser superior a la " + " \ nmitad de la dimension mas chica del Tablero de Juego " ); maxBarcos = Usuario . entero ( " Ingrese nuevamente la cantidad maxima de barcos " + " que se puede agregar al Tablero : " ); } Tablero tablero = new Tablero ( largoTablero , anchoTablero , maxBarcos ); Oponente rival = new Oponente (); int opcion = -1; while ( opcion != 0) { // Pedimos al usuario que elija una de las opciones opcion = Usuario . entero ( " Que desea hacer ?\ n (1) Agregar un barco a la flota \ n " + " (2) Poblar Tablero al eatoria mente \ n " + " (3) Quitar barco de la flota \ n " + " (4) Mostrar el estado actual de la flota \ n " + " (5) Mostrar el tablero \ n " + " (6) Simular ataque \ n " + " (0) Salir " ); if ( opcion == 1) { // Pedimos la informacion al usuario int tipo = Usuario . entero ( " Ingrese el tipo de barco que desea agregar : " ); int orientacion = Usuario . entero ( " Ingrese su orientacion :\ n (1) " + " Vertical \ n (2) Horizontal " );

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

27

char orienta ; if ( orientacion == 1) orienta = V ; else orienta = H ; int fila = Usuario . entero ( " Ingrese la fila en que desea que este : " ); int columna = Usuario . entero ( " Ingrese la columna en que desea que este : " ); // Creamos el barco y lo agregamos Barco barco = new Barco ( tipo , orienta ); if ( tablero . agregarBarco ( barco , fila , columna )) { Usuario . mensaje ( " El barco fue agregado a la flota s a t i s f a c t o r i a m e n t e ! " ); } else { Usuario . mensaje ( " No fue posible agregar el barco a la flota . " + " \ nIntente con parametros distintos . " ); } } else if ( opcion == 2) { tablero = new Tablero ( largoTablero , anchoTablero , maxBarcos ); tablero . poblarTablero (); } else if ( opcion == 3) { // Pedimos el tipo del barca para identificarlo int tipo = Usuario . entero ( " Ingrese el tipo del barco que desea quitar : " ); if ( tablero . hundirBarco ( tipo )) { Usuario . mensaje ( " El barco fue quitado de la flota . " ); } else { Usuario . mensaje ( " No fue posible quitar el barco de la flota . " ); } } else if ( opcion == 4) { tablero . m o s t r a r E s t a d o F l o t a (); } else if ( opcion == 5) { tablero . mostr arTable ro (); } else if ( opcion == 6) { int [] ataque = rival . atacar ( largoTablero - 1 , anchoTablero - 1); tablero . recibirAtaque ( ataque ); } } } }

. El programa lo dividiremos en 3 subconjuntos incrementales, de acuerdo a las necesidades se naladas. Se le recomienda no comenzar con el siguiente subconjunto sino hasta terminar y probar el funcionamiento correcto del subconjunto actual, a n de que su desarrollo sea consistente. Incremento 1 Para completar el primer incremento, deber a implementar completamente la clase Barco. A trav es de esta representaremos los barcos que participan del juego. Un barco queda caracterizado por su tipo y su orientaci on dentro del tablero de juego. Adem as, resultar a trascendente asociar a un barco tanto la cantidad de veces que ha sido impactado por un ataque rival, como su estado en un determinado instante: si a un permanece a ote o se ya se ha hundido. A continuaci on se detallan los m etodos que deber a tener esta clase: 1. Barco(int tipo, char orientacion) Constructor de la clase. Recibe la inicializaci on de sus caracter sticas esenciales. Un barco se modela como una hilera de segmentos. Luego, su ancho es unitario y su largo quedar a denido por el tipo de barco. El largo m nimo para un barco es 2. Su orientacion puede ser horizontal (H) o vertical (V). 2. void recibirImpacto() Incrementa la cantidad de impactos recibidos por ataques del rival, y actualiza el estado del barco si dicha cantidad ha alcanzado el m aximo admisible seg un el tipo de barco. Dado que se trata de una versi on simplicada del juego, el m aximo de ataques certeros que puede recibir un barco equivale a su largo (su tipo), sin importar si un mismo segmento del barco es atacado m as de una vez por el rival. De esta manera, para destruir un barco no es necesario que sean IIC1103 Cap tulo 7: Ordenaci on y B usqueda 28

impactados todos los segmentos de un barco. Por ejemplo, si un barco tipo 4 es alcanzado 3 veces en un mismo segmento y una vez en cualquier otro, su estado debe cambiar (el barco se hunde ). 3. M etodos para poder obtener estas 4 caracter sticas (getters ). Por otro lado, para este incremento deber a implementar parcialmente la clase Tablero, que representar a la supercie de juego. Esta clase queda caracterizada por sus dimensiones (largo y ancho) y por la lista de barcos que han sido creados y agregados al tablero (su ota ). Dado que el juego impide que dos barcos est en ocupando un mismo espacio, deber a modelar el tablero de manera tal que almacene informaci on acerca de cu ales posiciones se encuentran ocupadas y cu ales no. Entonces, deber a crear un arreglo bidimensional inicializado con el valor 1 en todas sus celdas para representar el vac o inicial del tablero. Al agregar un barco al tablero, deber a poner en las posiciones correspondientes el ndice del barco dentro de la ota. Por ejemplo, el primer barco agregado al tablero de juego utilizar a el ndice 0 dentro de la lista, por lo que todas las posiciones que cubra este barco en el tablero de juego, deber an contener el valor 0 en vez del valor 1. El siguiente ejemplo le permitir a entender mejor la situaci on. Suponga que las dimensiones del tablero son 8 de largo por 10 de ancho. Luego, se agrega un barco de tipo 3 con orientaci on H en la posici on (3,2), y otro de tipo 5 con orientaci on V en la posici on (0,6). En tal caso, el arreglo bidimensional quedar a de la siguiente forma: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1. Tablero(int filas, int columnas, int barcos) Constructor de la clase. Recibe las dimensiones de la supercie de juego, y la cantidad m axima de barcos que pueden ser agregados al tablero. En la implementaci on dada del m etodo main observar a que este u ltimo n umero debe cumplir con cierta restricci on. 2. agregarBarco(Barco barco, int fila, int columna) Permite agregar barco al tablero de juego a partir de la posici on determinada por (fila, columna). Estas coordenadas corresponden directamente a los ndices del arreglo bidimensional, y seg un la orientaci on del barco representan el extremo superior (V) o izquierdo (H) de este. Verica, de acuerdo a la cantidad m axima de barcos que admite el tablero, si es posible agregar un nuevo barco al tablero y si el tipo de barco que se desea agregar es v alido y no hay uno igual ya en la ota. Adem as, revisa si las coordenadas son v alidas, si no sobrepasar a los l mites del tablero seg un su orientaci on, y si los espacios requeridos para la operaci on est an desocupados. Si no cumple con alguna de estas condiciones, retornar a false. En caso contrario, inserta el barco al nal de la lista (o ota) y actualiza las posiciones del arreglo bidimensional con el n umero del ndice que ocup o en la lista, y luego retorna true. 3. void mostrarTablero() Muestra en la consola una visualizaci on gr aca del estado actual del tablero, similar a la mostrada m as arriba, pero reemplazando al imprimir los 1 por el caracter . Luego, para cada barco de la ota, muestra la cantidad de impactos recibidos por ataques del rival y, si corresponde, si ya fue hundido. IIC1103 Cap tulo 7: Ordenaci on y B usqueda 29

La clase Tablero deber a tener los siguientes m etodos:

El barco 0 ha recibido 2 impactos El barco 1 ha recibido 0 impactos El barco 2 ha recibido 4 impactos (ya hundido) Incremento 2 Para completar el segundo incremento, su programa debe complementar la clase Tablero con los siguientes m etodos: 1. boolean hundirBarco(int tipo) Permite quitar un barco del tablero, como tambi en de su lista asociada, solamente seg un el tipo del barco a eliminar dada la caracter stica de que en la ota no puede haber m as de un barco por cada tipo posible. Si el barco no existe en la ota retorna false. Observe que al remover un barco de la lista, debe actualizarla de manera que todos los barcos agregados con posterioridad al que se quiere eliminar sean desplazados dentro de la lista, a n de que no quede un espacio vac o en la lista ni se desperdicie un ndice. En relaci on a esto u ltimo, no olvide hacer lo propio con la representaci on de la ota en el arreglo bidimensional, disminuyendo los ndices de los barcos que correspondan en una unidad. Finalmente, retorna true. 2. void mostrarEstadoFlota() Muestra en la consola el estado de la ota. Para ello, crea un arreglo auxiliar con los barcos activos de la ota (aquellos que a un sobreviven ), y lo ordena crecientemente seg un la cantidad de impactos que a un pueden recibir. Finalmente, muestra un resumen como el siguiente: Los barcos de la Flota a un activos son: Barco Tipo 4 ha recibido 1 impactos Barco Tipo 5 ha recibido 3 impactos Barco Tipo 3 ha recibido 2 impactos Incremento 3 Para completar el tercer incremento, su programa debe agregar los siguientes m etodos a la clase Tablero: 1. void poblarTablero() Permite poblar un Tablero de acuerdo a sus par ametro de inicializaci on. Ocupando el m etodo Aleatorio.entero del paquete del curso y el m etodo agregarBarco ya implementado por Usted, genera la informaci on necesaria para crear los barcos que corresponda y agregarlos exitosamente a la ota. 2. void recibirAtaque(int[] coordenadas) Permite conocer los resultados de un ataque del oponente. Revisa si en el arreglo bidimensional la posici on representada por (coordenadas[0], coordenadas[1]) est a vac a u ocupada por alg un segmento de un barco. Si el ataque fue certero, invoca al m etodo recibirImpacto() del barco afectado. Finalmente, seg un sea el caso, muestra en la consola una de las siguientes alternativas de mensaje: Ataque a (6, 0): AGUA! Ataque a (7, 1): FUEGO! El barco atacado a un sobrevive! Ataque a (2, 4): FUEGO! El barco atacado se ha hundido! Criterios de soluci on Posible soluci on
public class Barco { private int tipo ;

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

30

private char orientacion ; private boolean derribado ; private int numImpactos ; public Barco ( int tipo , char orientacion ) { this . tipo = tipo ; this . orientacion = orientacion ; this . derribado = false ; this . numImpactos = 0; } public void re cibirIm pacto () { numImpactos ++; if ( numImpactos == tipo ) derribado = true ; } public int getTipo () { return tipo ; } public int getO rientac ion () { return orientacion ; } public boolean isDerribado () { return derribado ; } public int getN umImpac tos () { return numImpactos ; } } import iic1103Packa ge .*; public class Tablero { private int [][] superficie ; private Barco [] flota ; private int c antidad Barcos ; public Tablero ( int filas , int columnas , int barcos ) { // Inicializamos los atributos de acuerdo a las ca ra c te ri st i ca s indicadas en el enunciado flota = new Barco [ barcos ]; cantidadBar cos = 0; superficie = new int [ filas ][ columnas ]; for ( int i = 0; i < superficie . length ; i ++) for ( int j = 0; j < superficie [0]. length ; j ++) superficie [ i ][ j ] = -1; } public boolean agregarBarco ( Barco barco , int fila , int columna ) { // Revisamos si aun no se han agregado todos los barcos posibles if ( cantidad Barcos == flota . length ) return false ; // Revisamos si ya existe un barco del mismo tipo en la flota , // o si el tipo no esta permitido para el tamano de la flota for ( int i = 0; i < cant idadBar cos ; i ++) if ( barco . getTipo () == flota [ i ]. getTipo () || barco . getTipo () < 2 || barco . getTipo () > flota . length + 1) return false ; // Revisamos que la posicion en que se quiere agregar un barco sea permitida if ( fila < 0 || fila >= superficie . length || columna < 0 || columna >= superficie [0]. length ) return false ; // Dependiendo de la orientacion y el tipo del barco que se quiere agregar , revisamos que " alcance " // a ser incluido en la posicion deseada if ( barco . getOri entacio n () == V ) { if ( fila + barco . getTipo () > superficie . length ) return false ; } else { // barco . getOrien tacion () == H if ( columna + barco . getTipo () > superficie [0]. length ) return false ; } // Revisamos si el espacio necesario para agregar el barco se encuentra desocupado if ( barco . getOri entacio n () == V ) { for ( int i = 0; i < barco . getTipo (); i ++) { if ( superficie [ fila + i ][ columna ] != -1) return false ;

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

31

} } else { // barco . getOrien tacion () == H for ( int i = 0; i < barco . getTipo (); i ++) { if ( superficie [ fila ][ columna + i ] != -1) return false ; } } // Como a esta altura ya se han superado con exito las restricciones de factibilidad , // agregamos el barco al tablero ... if ( barco . getOri entacio n () == V ) { for ( int i = 0; i < barco . getTipo (); i ++) superficie [ fila + i ][ columna ] = cantid adBarco s ; } else { // barco . getOrien tacion () == H for ( int i = 0; i < barco . getTipo (); i ++) superficie [ fila ][ columna + i ] = cantid adBarco s ; } // ... y a la flota flota [ cant idadBarc os ] = barco ; cantidadBar cos ++; return true ; } public boolean hundirBarco ( int tipo ) { // Buscamos el barco a hundir de acuerdo a su tipo int indice = -1; for ( int i = 0; i < cant idadBar cos ; i ++) { if ( flota [ i ]. getTipo () == tipo ) { indice = i ; break ; } } // Si indice continua en -1 , entonces el barco que se desea eliminar no esta en la flota if ( indice == -1) return false ; // Lo quitamos de la flota ( corremos un espacio " a la izquierda " a todos los barcos agregados // con posterioridad al barco impactado por el enemigo )... for ( int i = indice ; i < cantidadBarcos -1; i ++) flota [ i ] = flota [ i +1]; cantidadBarcos - -; // ... y lo quitamos del tablero for ( int i = 0; i < superficie . length ; i ++) { for ( int j = 0; j < superficie [ i ]. length ; j ++) { // Si encontramos una seccion del barco impactado por el enemigo , la " hundimos " if ( superficie [ i ][ j ] == indice ) superficie [ i ][ j ] = -1; // Si encontramos una seccion de un barco que fue agregado posteri ormente a la flota , // actualizamos su indice en el tablero else if ( superficie [ i ][ j ] > indice ) superficie [ i ][ j ] = superficie [ i ][ j ] - 1; } } return true ; } public void m o s t r a r E s t a d o F l o t a () { Usuario . mens ajeConso la ( " " ); // Ocupamos un arreglo auxiliar a fin de no alterar nuestra flota original Barco [] barcosActivos ; int activos = 0; // Contabiliz amos cuantos barcos sobreviven a fin de incializar el arreglo auxiliar for ( int i = 0; i < cant idadBar cos ; i ++) { if (! flota [ i ]. isDerribado ()) activos ++; } barcosActivos = new Barco [ activos ]; // Separamos los barcos activos de los hundidos , // dejando una " copia " de los activos en el arreglo auxiliar

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

32

int v = 0; for ( int i = 0; i < cant idadBar cos ; i ++) { if (! flota [ i ]. isDerribado ()) { barcosActivos [ v ] = flota [ i ]; v ++; } } // Utilizando BubbleSort , ordenamos el arreglo de acuerdo al enunciado Barco aux ; for ( int i = 0; i < barcosActivos . length - 1; i ++) { for ( int j = 0; j < barcosActivos . length - 1 - i ; j ++) { // Ordenamos creci entement e segun la cantidad de impactos que aun pueden recibir if ( barcosActivos [ j ]. getTipo () - barcosActivos [ j ]. getNum Impactos () > barcosActivos [ j + 1]. getTipo () - barcosActivos [ j + 1]. getN umImpac tos ()) { aux = barcosActivos [ j ]; barcosActivos [ j ] = barcosActivos [ j + 1]; barcosActivos [ j + 1] = aux ; } } } // Mostramos el estado de la flota en consola Usuario . mens ajeConso la ( " Los barcos de la Flota que aun sobreviven son : " ); for ( int i = 0; i < barcosActivos . length ; i ++) Usuario . mensa jeConso la ( " Barco Tipo " + barcosActivos [ i ]. getTipo () + " , ha recibido " + barcosActivos [ i ]. g etNumIm pactos () + " impactos " ); } public void mo strarTa blero () { Usuario . mens ajeConso la ( " " ); // Mostramos cada casillero del tablero , reemplazando los caracteres segun corresponda for ( int i = 0; i < superficie . length ; i ++) { String linea = " " ; for ( int j = 0; j < superficie [ i ]. length ; j ++) { if ( superficie [ i ][ j ] == -1) linea += " ~ " ; else linea += superficie [ i ][ j ] + " " ; } Usuario . mensa jeConso la ( linea ); } // De manera similar , mostramos el estado de cada barco for ( int i = 0; i < cant idadBar cos ; i ++) { String linea = " El barco " + i + " ha recibido " + flota [ i ]. g etNumImp actos () + " impactos " ; if ( flota [ i ]. isDerribado ()) linea += " ( hundido ) " ; Usuario . mensa jeConso la ( linea ); } } public void poblarTablero () { Barco barcoAux ; char orientacion ; int fila , columna ; // Agregamos todos los barcos a la flota for ( int i = 0; i < flota . length ; i ++) { boolean agregarOK = false ; while (! agregarOK ) { // Definimos la orientacion del barco if ( Aleatorio . entero (0 , 1) == 0) orientacion = V ; else orientacion = H ; // Creamos el barco barcoAux = new Barco ( i + 2 , orientacion ); // Definimos las coordenadas fila = Aleatorio . entero (0 , superficie . length ); columna = Aleatorio . entero (0 , superficie [0]. length ); agregarOK = agregarBarco ( barcoAux , fila , columna ); } } } public void recibirAtaque ( int [] coordenadas ) {

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

33

Usuario . mens ajeConso la ( " " ); // Si la celda esta vacia , el ataque no produjo danos if ( superficie [ coordenadas [0]][ coordenadas [1]] == -1) { Usuario . mensa jeConso la ( " Ataque a ( " + coordenadas [0] + " , " + coordenadas [1] + " ): AGUA ! " ); return ; } // El ataque cayo sobre uno de los barcos de la flota flota [ superficie [ coordenadas [0]][ coordenadas [1]]]. recibir Impacto (); Usuario . mens ajeConso la ( " Ataque a ( " + coordenadas [0] + " , " + coordenadas [1] + " ): FUEGO ! " ); if ( flota [ superficie [ coordenadas [0]][ coordenadas [1]]]. isDerribado ()) Usuario . mensa jeConso la ( " El barco atacado se ha hundido ! " ); else Usuario . mensa jeConso la ( " El barco atacado aun sobrevive ! " ); } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

34

Problema 14: Grupos de Novatos


Enunciado Como bien Ud. sabe, los novatos de Ingenier a son acogidos durante el primer a no por el Cuerpo de Tutores. En particular, durante el primer semestre, est an en un grupo con otros novatos desarrollando un proyecto para el curso Desaf os de la Ingenier a. Para formar los grupos, el Cuerpo de Tutores considera una serie de variables, tales como paquete al que pertenecen los novatos, el sexo, si son de regiones, etc. Todos los grupos tienen novatos del mismo paquete. Usted deber a implementar un programa que permita agrupar a los novatos seg un ciertas variables, adem as de permitir realizar operaciones sobre sus datos. El proceso suele ser m as complicado que el que Ud. implementar a. Para la realizaci on del ejercicio usted cuenta con 3 clases ya implementadas que se detallan a continuaci on.
public class DBNovatos { // Esta clase representa los datos de los novatos private Novato [] novatos ; public DBNovatos () { // Constructor de la clase }

public void cargarDatos () { ... // Carga los datos de los novatos } public Novato [] ge tL i st aN ov a to s () { ... // Retorna la lista de los novatos } } public class Novato { private int id ; private String nombre ; private int puntaje ; public public public public public public public Novato ( int id , String nombre , int puntaje ) { ... } int getId () { return id ; } void setId ( int id ) { this . id = id ; } String getNombre () { return nombre ; } void setNombre ( String nombre ) { this . nombre = nombre ; } int getPuntaje () { return puntaje ; } void setPuntaje ( int puntaje ) { this . puntaje = puntaje ; }

// Retorna en un string los datos del novato public String getDat osNovat o () { return " id : " + id + " \ tnombre : " + nombre + " \ tpuntaje : " + puntaje ; } } import iic1103Packa ge .*; public class Principal { public static void main ( String [] args ) { // Inicializa cion de la base de datos y ordenamiento de la lista . DBNovatos db = new DBNovatos (); // El numero de paquetes es 5 , y el de grupos por paquete es 4 A rm aP a qu e t e s G r u p o s apg = new A r m a P a q u e t e s G r u p o s (4 , 5); apg . ordenarLista ( db . g e tL is ta N ov at os ()); apg . armarGrupos ( apg . g e t L i s t a O rd e n a d a ()); Usuario . mensaje ( " Base de datos de novatos cargada y ordenada segun puntajes " ); int opcion = 0; // Menu de opciones while ( opcion != 4) { opcion = Usuario . entero ( " Ingrese opcion :\ n1 : Listar segun puntajes \ n2 : Intercambiar novatos \ n3 : " + " Listar todos los novatos \ n4 : Salir " ); while ( opcion < 1 || opcion > 4) opcion = Usuario . entero ( " OPCION INVALIDA \ nIngrese opcion :\ n1 : Listar segun puntajes \ n2 : " + " Intercambiar novatos \ n3 : Listar todos los novatos \ n4 : Salir " ); switch ( opcion ) {

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

35

case 1: int nMenor = Usuario . entero ( " Ingrese cota menor de puntaje " ); int nMayor = Usuario . entero ( " Ingrese cota mayor de puntaje " ); apg . l i s t a S e g u n R a n g o s ( nMenor , nMayor ); break ; case 2: int n1Id = Usuario . entero ( " Ingrese primer novato a intercambiar " ); int n2Id = Usuario . entero ( " Ingrese segundo novato a intercambiar " ); apg . i n t e r c a m b i a r N o v a t o s ( apg . getNovato ( n1Id ) , apg . getNovato ( n2Id )); break ; case 3: apg . i m p r i m i r L i s t a C o m p l e t a (); default : break ; } } } }

. El programa lo dividiremos en 3 subconjuntos incrementales, de acuerdo a las necesidades se naladas. Se le recomienda no comenzar con el siguiente subconjunto sino hasta terminar y probar el funcionamiento correcto del subconjunto actual, a n de que su desarrollo sea consistente. Incremento 1 Para completar el primer incremento, deber a implementar parte de la clase ArmaPaquetesGrupos, la cual permitir a realizar las tareas previamente descritas. Utiliza intensivamente la clase Novato, que ya viene implementada y cuyos m etodos podr a apreciar en el respectivo archivo .java; NO LA MODIFIQUE. A continuaci on se detallan los m etodos que deber a tener ArmaPaquetesGrupos para este primer incremento: 1. public ArmaPaquetesGrupos(int gruposPorPqte, int nroPaquetes) Constructor de la clase. gruposPorPqte especica el n umero m aximo de grupos que tendr a cada paquete, nroPaquetes especica el m aximo de paquetes en los que se dividir a a los novatos. 2. public Novato[] ordenarLista(Novato[] listaNovatos) Ordena la lista de novatos seg un puntaje de forma decreciente1 . Retorna un arreglo unidimensional de tipo Novato. 3. public void armarGrupos(Novato[] listaNovatos) Dado un arreglo de objetos de tipo Novato2 , dene a qu e paquete y grupo pertenece cada novato. Para cumplir esta tarea, Ud. deber a tener como atributo de esta clase un arreglo bidimensional de tipo int denominado relNovatoGrupo, donde el primer ndice represente el Id del novato3 , y el segundo corresponda al n umero de paquete, ambos numerados desde el cero. El valor almacenado en cada celda de relNovatoGrupo[id][paquete] corresponde al n umero de grupo asignado. Para poder llenar la matriz anterior, debemos determinar primero a qu e paquete pertenece cada alumno, y luego asignarle un n umero de grupo v alido para ese paquete. Para armar un paquete, la idea es que todos tengan personas de todos los rangos de puntajes (altos, medios y bajos). Para efectos de este ejercicio, el n umero de paquete para cada novato se calcula as : #paquete = (indexOrden) %(nroP aquetes) donde:
sea, de mayor a menor puntaje. No se preocupe ante igualdades de puntaje entre 2 o m as alumnos; para esos casos, resuelva seg un le parezca. Puede utilizar algoritmos de ordenaci on tales como BubbleSort, InsertSort o SelectionSort. 2 Que previamente haya sido retornado por el m etodo ordenarLista(..) 3 Revise la implementaci on de la clase Novato. Ella tiene 3 atributos: int id, que hace las veces de n umero de alumno; String nombre, que es el nombre completo del alumno; e int puntaje, que corresponde al puntaje ponderado de ingreso a la carrera
1O

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

36

El % corresponde al operador de m odulo de Java.

indexOrden corresponde al ndice del arreglo listaNovatos[], pasado como par ametro. nroPaquetes el m aximo de paquetes, especicado al momento de la construcci on de la clase.

El n umero de grupo para cada novato se calcula de la siguiente forma: #grupo = ((#novatosP aquete) %(gruposP orP qte) + 1) + (#paquete) (gruposP orP qte) donde: #novatosPaquete especica la cantidad de novatos del paquete correspondiente, a los cuales ya se les ha asignado grupo4 . gruposPorPqte corresponde al atributo especicado en el constructor de la clase. #paquete es el n umero de paquete calculado previamente para el novato en cuesti on.

Asuma para este c alculo que habr a sucientes alumnos para que exista el n umero de grupos por paquetes se nalado al momento de la creaci on de la clase. A continuaci on veremos una representaci on cticia de relNovatoGrupo[][], para 10 alumnos, 5 paquetes y 2 grupo de alumnos por paquete5 : 1 0 0 0 2 0 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0 0 0 5 0 0 0 6 0 0 0 0 0 0 7 0 8 0 0 0 9 10 0 0 0 0 0 0

Las las representan a los novatos (indexados por su Id), y las columnas representan a los paquetes (indexados por su n umero). Por ejemplo, podemos ver que la segunda la corresponde al alumno con Id = 1. Si nos desplazamos hacia la derecha por esta misma la, vemos que todos los n umeros son 0, salvo uno (en este caso, el 3, que corresponde a su n umero de grupo). Podemos tambi en revisar que la columna asociada a esta celda es la que corresponde al n umero de paquete (en este caso, como es la segunda columna, corresponde al paquete 1). Note que un novato puede pertenecer a un s olo grupo y a un s olo paquete. 4. public void imprimirListaCompleta() Imprime en consola la lista completa de alumnos, ordenada decrecientemente por puntaje. Un ejemplo de output para un alumno es el siguiente: id: 8 nombre: VICENCIO ALBERTO puntaje: 818 Al nal de la lista, se debe imprimir el n umero de alumnos mostrados en consola (por ejemplo: ** Se encontraron 20 registros) 5. Debe agregar m etodos para poder obtener los atributos que debe tener la clase (getters ). Si entase libre de agregar otros m etodos seg un estime necesario para realizar de mejor forma su tarea, pero debe cumplir como m nimo con los espec cados (que deben ce nirse elmente a las deniciones). Esto es v alido tambi en para los otros 2 incrementos.
4 Este 5 El

valor no incluye al novato sobre el que se est a calculando su n umero de grupo. resultado es irreal: grupos de un s olo alumno!. Es s olo para ilustrar el c omo ser a la matriz requerida.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

37

Incremento 2 Para completar el segundo incremento, su programa debe agregar los siguientes m etodos a la clase ArmaPaquetesGrupos: 1. public Novato getNovato(int id) Retorna un objeto de tipo Novato si el id existe en la lista de novatos, null si no. 2. public int getNroPqte(Novato n) retorna el n umero de paquete asociado al novato, -1 si no existe (si n es igual a null). 3. public int getNroGrupo(Novato n) retorna el n umero de grupo asociado al novato, -1 si no existe (si n es igual a null). Adem as deber a mejorar el m etodo imprimirListaCompleta(), para que el output de cada novato incluya tambi en el n umero de grupo. Un ejemplo es el siguiente: id: 8 nombre: VICENCIO ALBERTO puntaje: 818 grupo : 1 Recuerde que la clase Novato NO posee atributos que especiquen su n umero de paquete o grupo, por lo que deber a realizar su b usqueda en la matriz que relaciona a los novatos con los paquetes y grupos. Incremento 3 Para completar el tercer incremento, su programa debe agregar los siguientes m etodos a la clase ArmaPaquetesGrupos: 1. public void listaSegunRangos(int menor,int mayor) Muestra en consola una lista con los alumnos que se encuentren en el rango de puntajes especicado por menor y mayor(ambos inclusive). El formato es una l nea por alumno, con los mismos datos que muestra imprimirListacompleta(). Debe mostrar al nal de la lista el n umero de alumnos est an dentro del rango de puntajes (por ejemplo, ** Se encontraron 9 registros). 2. public void intercambiarNovatos(Novato n1, Novato n2) Permite intercambiar de grupo a dos novatos. Para llevar a cabo esta operaci on, los dos alumnos deben ser del mismo paquete, pero no pertenecer al mismo grupo. Este m etodo debe validar tales casos, informando con un mensaje que no se pudo realizar el intercambio. Criterios de soluci on Posible soluci on
import iic1103Packa ge .*; public class A r m a P a q u e t e s G r u p o s { private private private private int [][] re lNovato Grupo ; Novato [] listaOrdenada ; int nroPaquetes ; int gruposPorPqte ;

// Constructor public A r ma P a q u e t e s G r u p o s ( int gruposPorPqte , int nroPaquetes ) { this . gruposPorPqte = gruposPorPqte ; this . nroPaquetes = nroPaquetes ; } // Setters ( y tambien getters , aunque no se soliciten en el enunciado ) public int g e t G r u p o s P o r P q te () { return gruposPorPqte ; } public void s e t G r u p o s P o r P q t e ( int gruposPorPqte ) { this . gruposPorPqte = gruposPorPqte ; } public Novato [] g e t L i s t a O r d e n a d a () {

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

38

return listaOrdenada ; } public void s e t L i s t a O r d e n a d a ( Novato [] listaOrdenada ) { this . listaOrdenada = listaOrdenada ; } public int getN roPaque tes () { return nroPaquetes ; } public void se tNroPaq uetes ( int nroPaquetes ) { this . nroPaquetes = nroPaquetes ; } public int [][] g e t R e l N o v a t o G r u p o () { return relNo vatoGru po ; } public void s e t R e l N o v a t o G r u p o ( int [][] re lNovato Grupo ) { this . relNovatoG rupo = relNovat oGrupo ; } // Ordena la lista segun puntaje . Utiliza BubbleSort . public Novato [] ordenarLista ( Novato [] listaNovatos ) { for ( int i = 0; i < listaNovatos . length ; i ++) { for ( int j = 0; j < listaNovatos . length ; j ++) { if ( listaNovatos [ i ]. getPuntaje () > listaNovatos [ j ]. getPuntaje ()) { Novato aux = new Novato ( listaNovatos [ i ]. getId () , listaNovatos [ i ]. getNombre () , listaNovatos [ i ]. getPuntaje ()); listaNovatos [ i ] = listaNovatos [ j ]; listaNovatos [ j ] = aux ; } } } listaOrdenada = listaNovatos ; return listaNovatos ; } public void armarGrupos ( Novato [] listaNovatos ) { relNovatoGr upo = new int [ listaNovatos . length ][ nroPaquetes ]; for ( int i = 0; i < listaNovatos . length ; i ++) { relNovatoGr upo [ listaNovatos [ i ]. getId ()][ i % nroPaquetes ] = -1; } for ( int i = 0; i < nroPaquetes ; i ++) { int cuentaGrupo = 0; for ( int j = 0; j < listaNovatos . length ; j ++) { if ( relNova toGrupo [ j ][ i ] == -1) { relN ovatoGru po [ j ][ i ] = ( cuentaGrupo % gruposPorPqte + 1) + ( i ) * gruposPorPqte ; cuentaGrupo ++; } } } } public void l i s t a S e g u n R a n g o s ( int menor , int mayor ) { Usuario . mens ajeConso la ( " ** Resultados de su consulta : " ); int cuenta Aciertos = 0; for ( int i = 0; i < listaOrdenada . length ; i ++) { if ( listaOrdenada [ i ]. getPuntaje () >= menor && listaOrdenada [ i ]. getPuntaje () <= mayor ) { cuentaAciert os ++; int nroGrupo = getNroGrupo ( listaOrdenada [ i ]); Usuario . mensa jeConso la ( listaOrdenada [ i ]. getDa tosNova to () + " \ tgrupo : " + nroGrupo ); } } Usuario . mens ajeConso la ( " ** Se encontraron " + cu entaAcie rtos + " registros " ); }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

39

public void i m p r i m i r L i s t a C o m p l e t a () { Usuario . mens ajeConso la ( " ** Resultados de su consulta : " ); int cuenta Aciertos = 0; for ( int i = 0; i < listaOrdenada . length ; i ++) { cuentaAcier tos ++; // Usuario . mensaje ( listaOrdenada [ i ]. m u e s t r a D a t o s N o v a t o ()); int nroGrupo = getNroGrupo ( listaOrdenada [ i ]); Usuario . mensa jeConso la ( listaOrdenada [ i ]. getDa tosNova to () + " \ tgrupo : " + nroGrupo ); } Usuario . mens ajeConso la ( " ** Se encontraron " + cu entaAcie rtos + " registros " ); } public void i n t e r c a m b i a r N o v a t o s ( Novato n1 , Novato n2 ) { if ( n1 == null || n2 == null ) { Usuario . mensaje ( " Uno de los novatos no existe . Ingrese novatos que existan " ); return ; } // Buscamos los grupos de cada novato int grupon1 = getNroGrupo ( n1 ); int grupon2 = getNroGrupo ( n2 ); int pqten1 = getNroPqte ( n1 ); int pqten2 = getNroPqte ( n2 ); if ( grupon1 == grupon2 ) { Usuario . mensaje ( " No se pueden intercambiar porque son del mismo grupo " ); return ; } if ( pqten1 != pqten2 ) { Usuario . mensaje ( " No se pueden intercambiar porque son de distinto paquete " ); return ; } int aux = relNova toGrupo [ n1 . getId ()][ pqten1 ]; relNovatoGr upo [ n1 . getId ()][ pqten1 ] = relNov atoGrup o [ n2 . getId ()][ pqten1 ]; relNovatoGr upo [ n2 . getId ()][ pqten1 ] = aux ; } public int getNroGrupo ( Novato n ) { if ( n == null ) { return -1; } int nroGrupo = 0; int pqte = 0; while ( nroGrupo == 0) { if ( pqte >= nroPaquetes ) { nroGrupo = -1; break ; } nroGrupo = relNov atoGrup o [ n . getId ()][ pqte ]; pqte ++; } return nroGrupo ; } public int getNroPqte ( Novato n ) { if ( n == null ) { return -1; } int nroGrupo = 0; int pqte = 0; while ( nroGrupo == 0) { if ( pqte >= nroPaquetes ) { nroGrupo = -1; break ; } nroGrupo = relNov atoGrup o [ n . getId ()][ pqte ]; pqte ++; } if ( nroGrupo != -1) { return ( pqte - 1); } else { return -1; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

40

public Novato getNovato ( int id ) { for ( int i = 0; i < listaOrdenada . length ; i ++) { if ( listaOrdenada [ i ]. getId () == id ) { return listaOrdenada [ i ]; } } return null ; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

41

Problema 15: Muebles en Habitaci on


Enunciado Usted deber a implementar un programa que permita posicionar muebles dentro de una habitaci on. Su programa deber a permitir agregar muebles a la habitaci on para lo cual deber a buscar un lugar dentro de la habitaci on donde exista el espacio suciente para poner el mueble. Para la realizaci on del ejercicio usted cuenta con la clase Principal ya implementada y que se muestra a continuaci on.
import iic1103Packa ge .*; public class Principal { public static void main ( String [] args ) { int ancho H ab it a ci on = Usuario . entero ( " Ingrese el ancho de la habitacion : " ); int altoHa bitacion = Usuario . entero ( " Ingrese el alto de la habitacion : " ); int max = Usuario . entero ( " Ingrese la cantidad maxima de muebles : " ); Habitacion pieza = new Habitacion ( anchoHabitacion , altoHabitacion , max ); int opcion = -1; while ( opcion != 0) { // Pedimos al usuario que elija una de las opciones opcion = Usuario . entero ( " Que desea hacer ?\ n (1) Agregar Mueble \ n " + " (2) Agregar mueble en posicion especiica \ n " + " (3) Eliminar Mueble \ n " + " (4) Mostrar muebles ordenados por area \ n " + " (5) Ver habitacion \ n " + " (0) Salir " ); if ( opcion == 1) { // Pedimos la informacion al usuario String nombre = Usuario . texto ( " Ingrese el nombre del mueble " ); int ancho = Usuario . entero ( " Ingrese el ancho del mueble : " ); int alto = Usuario . entero ( " Ingrese el alto del mueble : " ); // Creamos el mueble y lo agregamos Mueble mueble = new Mueble ( nombre , ancho , alto ); if ( pieza . AgregarMueble ( mueble )) { Usuario . mensaje ( " Mueble agregado correctamente . " ); } else { Usuario . mensaje ( " No fue posible agregar el mueble . " ); } } else if ( opcion == 2) { // Pedimos la informacion al usuario String nombre = Usuario . texto ( " Ingrese el nombre del mueble " ); int ancho = Usuario . entero ( " Ingrese el ancho del mueble : " ); int alto = Usuario . entero ( " Ingrese el alto del mueble : " ); int fila = Usuario . entero ( " Ingrese la fila : " ); int columna = Usuario . entero ( " Ingrese la columna : " ); // Creamos el mueble y lo agregamos Mueble mueble = new Mueble ( nombre , ancho , alto ); if ( pieza . A g r e g a r M u e b l e P o s i c i o n ( mueble , fila , columna )) { Usuario . mensaje ( " Mueble agregado correctamente . " ); } else { Usuario . mensaje ( " No fue posible agregar el mueble . " ); } } else if ( opcion == 3) { // Pedimos el nombre del mueble a borrar String nombre = Usuario . texto ( " Ingrese el nombre del mueble " ); if ( pieza . Elimi narMueb le ( nombre )) { Usuario . mensaje ( " Mueble eliminado correctamente . " ); } else { Usuario . mensaje ( " No fue posible eliminar el mueble . " ); } } else if ( opcion == 4) { pieza . M o s t r a r M u e b l e s P o r A r e a (); } else if ( opcion == 5) { pieza . M o s t r a r H a b i t a c i o n (); } } } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

42

El programa lo dividiremos en 3 subconjuntos incrementales, de acuerdo a las necesidades se naladas. Se le recomienda no comenzar con el siguiente subconjunto sino hasta terminar y probar el funcionamiento correcto del subconjunto actual, a n de que su desarrollo sea consistente. Incremento 1 Para completar el primer incremento, deber a implementar la clase Mueble por completo, la cual representar aa un mueble dentro de su programa. Cada mueble se caracterizar a por su nombre, un ancho y un alto. A continuaci on se detallan los m etodos que deber a tener esta clase. 1. Mueble(String nombre, int ancho, int alto) Constructor de la clase. Recibe la inicializaci on de sus caracter sticas. 2. int CalcularArea() Retorna el area del mueble, la cual se calcula multiplicando el ancho por el alto. 3. M etodos para poder obtener las 3 caracter sticas. Adem as en este incremento deber a implementar la clase Habitacion, la cual representar a el espacio donde se deben poner los muebles. Esta clase se caracteriza por un ancho, un alto y por la lista de muebles que se han incorporado. Como dos muebles no pueden utilizar el mismo espacio deber a crear una matriz que permita saber cuales espacios se encuentran desocupados. Para esto su matriz debe inicializarla con el valor 1 en todas sus casillas, el cual indicar a que la matriz se encuentra vac a. Cuando agregue un mueble deber a poner en las casillas utilizadas por ese mueble el ndice del mueble dentro de la lista de muebles. Por ejemplo, el primer mueble en agregar utilizar a el ndice 0 dentro de la lista, por lo que todas las casillas que este utilice deber an contener el valor 0 en la matriz. Por ejemplo, si creo una habitaci on de 8 de ancho y 5 de alto, luego agrego un mueble de 3 de ancho y 2 de alto, y luego otro mueble de 1 por 4, la matriz debe quedar de la siguiente forma: 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

La clase Habitacion debe tener los siguientes m etodos: 1. Habitacion(int ancho, int alto, int maxMuebles) Constructor de la clase. Recibe el ancho y alto de la habitaci on, as como tambi en la cantidad m axima de muebles que puede contener. 2. boolean AgregarMueblePosicion(Mueble nuevoMueble, int fila, int col) Permite agregar un mueble en una posici on determinada. Verica que la posici on sea v alida (se encuentre en los l mites v alidos para la habitaci on), en caso de no ser v alida retorna false. Adem as verica que sea posible agregar el mueble en la posici on indicada para lo cual revisa si se encuentran vac os los espacios necesarios seg un las dimensiones del mueble (la posici on recibida simboliza a la esquina superior izquierda del mueble). Si es posible agregar el mueble, lo inserta al nal de la lista y marca las casillas ocupadas por este, retornando true. 3. void MostrarHabitacion() Muestra en la consola el estado actual de la habitaci on. Primero muestra la matriz seg un los valores que posee, reemplazando los 1 por la letra X (al mostrarla se debe ver de forma similar al ejemplo mostrado anteriormente, pero en vez de 1 deben aparecer X). Luego muestra la lista de muebles en la habitaci on, mostrando para cada uno el ndice que le corresponde y el nombre. IIC1103 Cap tulo 7: Ordenaci on y B usqueda 43

Incremento 2 Para completar el segundo incremento, su programa debe agregar los siguientes m etodos a la clase Habitacion: 1. boolean AgregarMueble(Mueble nuevoMueble) Permite agregar un nuevo mueble en la primera posici on que encuentre dentro de la habitaci on. Para esto busca en todas las posiciones si es posible agregar el mueble y si logra hacerlo retorna true. En caso de no poder agregarlo retorna false. HINT: Utilice el m etodo AgregarMueblePosicion. 2. void MostrarMueblesPorArea() Muestra en la consola los muebles ordenados de mayor a menor seg un el area que utilicen. Para cada mueble muestra el nombre y el area utilizada. Tengan cuidado en no desordenar el arreglo de muebles (deben trabajar en un arreglo auxiliar). Incremento 3 Para completar el tercer incremento, su programa debe agregar el siguiente m etodo a la clase Habitacion: 1. boolean EliminarMueble(String nombre) Permite eliminar un mueble de la habitaci on, seg un el nombre de este. Si el mueble no existe retorna false. Para eliminar un mueble debo removerlo de la lista de muebles y denir que las casillas que estaba utilizando ahora est an libres. Al removerlo de la lista debo mover todas los muebles que se encontraban despu es de el en la lista, para tapar el espacio dejado por el mueble eliminado. Con esto debo actualizar la matriz con los nuevos ndices de los muebles. Retorna true despu es de actualizar todo. Criterios de soluci on Posible soluci on
public class Mueble { private String nombre ; private int ancho ; private int alto ; public Mueble ( String nombre , int ancho , int alto ) { this . nombre = nombre ; this . ancho = ancho ; this . alto = alto ; } public public public public } import iic1103Packa ge .*; public class Habitacion { private int [][] espacio ; private Mueble [] listaMuebles ; private int numMuebles ; public Habitacion ( int ancho , int alto , int maxMuebles ) { // Inicializamos la lista de muebles segun el maximo ingresado listaMuebles = new Mueble [ maxMuebles ]; numMuebles = 0; // Inicializamos la matriz con el espacio . En un comienzo todos los // valores son -1 ya que todo esta desocupado . espacio = new int [ ancho ][ alto ]; for ( int i = 0; i < espacio . length ; i ++) { for ( int j = 0; j < espacio [ i ]. length ; j ++) { espacio [ i ][ j ] = -1; } } } String getNombre () { return nombre ; } int getAncho () { return ancho ; } int getAlto () { return alto ; } int CalcularArea () { return ancho * alto ; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

44

public boolean A g r e g a r M u e b l e P o s i c i o n ( Mueble nuevoMueble , int fila , int col ) { // Verificamos que sea posible agregar mas muebles if ( numMuebles == listaMuebles . length ) { return false ; } // Verificamos que la fila y la columna sean validas if ( fila < 0 || fila >= espacio . length || col < 0 || col >= espacio [0]. length ) { return false ; } // Revisamos que las dimensiones del mueble sean posibles a partir de la // posicion entregada if ( fila + nuevoMueble . getAlto () > espacio . length || col + nuevoMueble . getAncho () > espacio [0]. length ) { return false ; } // Revisamos si a partir de la posicion dada los espacios necesarios se // encuentran vacios for ( int i = fila ; i < fila + nuevoMueble . getAlto (); i ++) { for ( int j = col ; j < col + nuevoMueble . getAncho (); j ++) { // Revisamos si el espacio esta vacio , en caso de no estarlo // retornamos false ya que no sera posible agregar el mueble . if ( espacio [ i ][ j ] != -1) { return false ; } } } // Agregamos el mueble a la lista y a la matriz listaMuebles [ numMuebles ] = nuevoMueble ; for ( int i = fila ; i < fila + nuevoMueble . getAlto (); i ++) { for ( int j = col ; j < col + nuevoMueble . getAncho (); j ++) { espacio [ i ][ j ] = numMuebles ; } } // Aumentamos la cantidad de muebles numMuebles ++; return true ; } public boolean AgregarMueble ( Mueble nuevoMueble ) { // Recorremos todo el espacio intentando agregar nuestro mueble en cada // una de las posiciones // Si somos capaces de agregarlo en una de las posiciones , entonces // retornamos true . for ( int i = 0; i < espacio . length ; i ++) { for ( int j = 0; j < espacio [ i ]. length ; j ++) { if ( A g r e g a r M u e b l e P o s i c i o n ( nuevoMueble , i , j )) { return true ; } } } return false ; } public boolean Elim inarMueb le ( String nombre ) { // Buscamos el mueble segun el nombre recibido int indice = -1; for ( int i = 0; i < numMuebles ; i ++) { if ( listaMuebles [ i ]. getNombre (). equals ( nombre )) { indice = i ; break ; } } // Revisamos si realmente lo encontramos if ( indice == -1) { return false ; } // Lo eliminamos de la matriz . Ademas debemos actualizar los numeros de // aquellos muebles que se encuentren despues del mueble eliminado , // ya que al eliminarlo del arreglo todos // esos muebles disminuiran su indice en 1. for ( int i = 0; i < espacio . length ; i ++) { for ( int j = 0; j < espacio [ i ]. length ; j ++) { if ( espacio [ i ][ j ] == indice ) { espacio [ i ][ j ] = -1; } else if ( espacio [ i ][ j ] > indice ) { espacio [ i ][ j ] = espacio [ i ][ j ] - 1;

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

45

} } } // Ahora lo eliminamos del arreglo for ( int i = indice ; i < numMuebles - 1; i ++) { listaMuebles [ i ] = listaMuebles [ i + 1]; } numMuebles - -; return true ; } public void M o s t r a r M u e b l e s P o r A r e a () { // Hacemos un arreglo auxiliar , ya que no podemos cambiar el orden del // arreglo actual Mueble [] auxMuebles = new Mueble [ numMuebles ]; // Copiamos todos los muebles for ( int i = 0; i < numMuebles ; i ++) { auxMuebles [ i ] = listaMuebles [ i ]; } // Ordenamos el arreglo . En este caso utilizaremos BubbleSort for ( int i = 0; i < numMuebles - 1; i ++) { // Buscamos el mayor entre los que quedan int max = i ; for ( int j = i + 1; j < numMuebles ; j ++) { if ( auxMuebles [ j ]. CalcularArea () > auxMuebles [ max ]. CalcularArea ()) { max = j ; } } // Hacemos el intercambio de los elementos ( Swap ) Mueble aux = auxMuebles [ i ]; auxMuebles [ i ] = auxMuebles [ max ]; auxMuebles [ max ] = aux ; } // Mostramos cada uno de los elementos Usuario . mens ajeConso la ( " Lista de Muebles ordenados por area : " ); for ( int i = 0; i < numMuebles ; i ++) { Usuario . mensa jeConso la ( auxMuebles [ i ]. getNombre () + " : " + auxMuebles [ i ]. CalcularArea ()); } } public void M o s t r a r H a b i t a c i o n () { // Mostramos cada uno de los espacios . Donde aparezca un -1 lo // reemplazamos por una X for ( int i = 0; i < espacio . length ; i ++) { String linea = " " ; for ( int j = 0; j < espacio [ i ]. length ; j ++) { if ( espacio [ i ][ j ] == -1) { linea += X ; } else { linea += espacio [ i ][ j ]; } } Usuario . mensa jeConso la ( linea ); } // Mostramos los muebles junto con su indice for ( int i = 0; i < numMuebles ; i ++) { Usuario . mensa jeConso la ( i + " " + listaMuebles [ i ]. getNombre ()); } } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

46

Problema 16: Administraci on Banco


Enunciado Debe implementar un programa que simule un sistema de administraci on de un banco. Se le pide implementar dos clases: AdminCuentas, y Cuenta. La clase AdminCuentas consistir a en un sistema simple de administraci on de cuentas corrientes de un banco; la clase Cuenta, en informaci on detallada sobre una cuenta corriente de una persona. Adem as, existe una tercera clase, InterfazUsuario, que contiene el main del programa, y que ya est a implementada. Cuenta: Debe tener los siguientes atributos: El nombre de la persona asociada a la cuenta corriente en un String. El RUT de la persona asociada a la cuenta corriente en un String. El apellido de la persona asociada a la cuenta corriente en un String. La clave de la persona asociada a la cuenta corriente en un String. Un arreglo de enteros para almacenar los giros (salida de dinero). Adem as, la clase Cuenta debe tener los siguientes m etodos: public Cuenta(String nuevoNombre, String nuevoApellido, String nuevoRUT, String nuevaClave, int cantMax): El constructor crea un nuevo objeto Cuenta, recibiendo como par ametros el nombre, apellido, RUT y clave de la persona, y la cantidad m axima de dep ositos y giros que tendr a (es decir, puede almacenar hasta cantMax giros, y hasta cantMax dep ositos). Inicializa con un -1 el arreglo de dep ositos y el de giros. public String getNombre(): retorna el nombre de la persona. public String getRUT(): retorna el RUT de la persona. public String getApellido(): retorna el apellido de la persona. public String getClave(): retorna la clave de la persona.

Un arreglo de enteros para almacenar los dep ositos (entrada de dinero).

public boolean agregarDeposito(int monto): recibe un par ametro entero que debe agregar en el arreglo de dep ositos. Debe buscar el primer espacio desocupado en el arreglo (es decir, con valor distinto a -1), y almacenar el monto ah . Retorna true si pudo, false si el arreglo estaba lleno. public boolean agregarGiro(int monto): recibe un par ametro entero que debe agregar en el arreglo de giros. Debe buscar el primer espacio desocupado en el arreglo (es decir, con valor distinto a -1), y almacenar el monto ah . Retorna true si pudo, false si el arreglo estaba lleno. public int totalDepositos(): suma todos los dep ositos (es decir, los que est en en el arreglo con valor distinto a -1), y retorna la suma. public int totalGiros(): suma todos los giros (es decir, los que est en en el arreglo con valor distinto a -1), y retorna la suma. public int saldo(): retorna el saldo total (es decir, la resta entre el total de dep ositos y el de giros). public int mostrarTodo(): muestra un mensaje en pantalla con informaci on de los dep ositos y giros. En particular, debe indicar el nombre de la persona asociada a la cuenta, y mostrar una lista de todos los dep ositos, seguidos del total de dep ositos; una lista de todos los giros, seguida del total de giros; y el saldo total. IIC1103 Cap tulo 7: Ordenaci on y B usqueda 47

AdminCuentas: Debe tener los siguientes atributos: Un arreglo de objetos de tipo Cuenta (almacena Cuentas). Un entero indicando con la cantidad de objetos de tipo Cuenta actualmente almacenados en el arreglo. Adem as, la clase AdminCuentas debe tener los siguientes m etodos: public AdminCuentas(int maxCant): Constructor, recibe como par ametro un entero que indica la cantidad m axima de Cuentas permitida; es decir, cu antos objetos Cuenta puede almacenar como m aximo. public boolean crearCuenta(Cuenta nuevaCuenta): recibe como par ametro un objeto de tipo Cuenta, y lo agrega al arreglo de cuentas si existe un lugar disponible; si est a lleno, no hace nada. Retorna true si pudo crear la cuenta y agregarla al arreglo y false si no pudo por estar lleno. public void verCuentas(): muestra un mensaje en pantalla con una lista de todas las cuentas almacenadas en el arreglo, indicando, para cada uno, su posici on en la lista (partiendo de 1); y su Nombre, Apellido y RUT. Por ejemplo, para el que est a en el lugar 0 mostrar a 1) Nombre Apellido RUT (reemplazando Nombre, Apellido y RUT por los valores para ese caso), en la siguiente l nea el segundo, luego el tercero, etc. public Cuenta getCuenta(String RUT, String clave): recibe como par ametro un String con el RUT, y otro string con la clave. Debe buscar en el arreglo de cuentas una cuenta donde el RUT y clave sean iguales a los recibidos. Si la encuentra, retorna ese objeto Cuenta; si no encuentra una que corresponda, retorna null. La clase InterfazUsuario, que contiene el main del programa, viene ya implementada y se muestra a continuaci on.
import iic1103Packa ge .*; public class I nt er fa z Us ua r io { public static void main ( String [] args ) { // Crea sistema int capacidad = Usuario . entero ( " Ingrese la capacidad maxima de cuentas a administrar " + " ( mayor o igual a 3): " ); AdminCuentas admin = new AdminCuentas ( capacidad ); // Crea las cuentas predefinidas Cuenta c1 = new Cuenta ( " Juan " , " Perez " , " 123 " , " 123 " , 5); admin . crearCuenta ( c1 ); Cuenta c2 = new Cuenta ( " George " , " Bush " , " 234 " , " 234 " , 5); c2 . agrega rD e po si to (1000000); c2 . agrega rD e po si to (1000000); admin . crearCuenta ( c2 ); Cuenta c3 = new Cuenta ( " Hugo " , " Reyes " , " 4815162 -3 " , " 42 " , 5); c3 . agrega rD e po si to (16000000); c3 . agregarGiro (4815); admin . crearCuenta ( c3 ); // Menu boolean salir = false ; while (! salir ) { // Muestra menu y obtiene opcion int opcion = Usuario . entero ( " Elija una opcion :\ n (1) Ver cuentas " + " \ n (2) Crear cuenta \ n (3) Realizar deposito " + " \ n (4) Realizar giro \ n (5) Ver detalle y saldo cuenta \ n (6) Salir " ); if ( opcion == 1) { // Ver cuentas admin . verCuentas (); } else if ( opcion == 2) { // Crear cuenta // Obtenemos datos String nombre = Usuario . texto ( " Ingrese el nombre de la persona : " ); String apellido = Usuario . texto ( " Ingrese el apellido de la persona : " ); String RUT = Usuario . texto ( " Ingrese el RUT de la persona : " ); String clave = Usuario . texto ( " Ingrese una clave para la cuenta : " ); Cuenta nuevaCuenta = new Cuenta ( nombre , apellido , RUT , clave , 5);

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

48

} } } } }

// Agregamos if ( admin . crearCuenta ( nuevaCuenta )) { Usuario . mensaje ( " Cuenta creada . " ); } else { Usuario . mensaje ( " Cuenda no creada . " ); } else if ( opcion == 3) { // Realizar deposito // Obtenemos cuenta String RUT = Usuario . texto ( " Ingrese el RUT de la persona : " ); String clave = Usuario . texto ( " Ingrese la clave : " ); Cuenta buscada = admin . getCuenta ( RUT , clave ); // Realiza deposito if ( buscada != null ) { int monto = Usuario . entero ( " Ingrese el monto del deposito : " ); if ( buscada . ag re g ar De p os it o ( monto )) { Usuario . mensaje ( " Deposito ingresado . " ); } else { Usuario . mensaje ( " Depostio no ingresado , " ); } } else { Usuario . mensaje ( " RUT o clave incorrectos . " ); } else if ( opcion == 4) { // Realizar giro // Obtenemos cuenta String RUT = Usuario . texto ( " Ingrese el RUT de la persona : " ); String clave = Usuario . texto ( " Ingrese la clave : " ); Cuenta buscada = admin . getCuenta ( RUT , clave ); // Realiza deposito if ( buscada != null ) { int monto = Usuario . entero ( " Ingrese el monto del giro : " ); if ( buscada . agregarGiro ( monto )) { Usuario . mensaje ( " Giro ingresado . " ); } else { Usuario . mensaje ( " Giro no ingresado , " ); } } else { Usuario . mensaje ( " RUT o clave incorrectos . " ); } else if ( opcion == 5) { // Ver detalle cuenta // Obtenemos estudiante String RUT = Usuario . texto ( " Ingrese el RUT de la persona : " ); String clave = Usuario . texto ( " Ingrese la clave : " ); Cuenta buscada = admin . getCuenta ( RUT , clave ); // Muestra detalle if ( buscada != null ) { buscada . mostrarTodo (); } else { Usuario . mensaje ( " RUT o clave incorrectos . " ); } else if ( opcion == 6) { // Salir salir = true ;

Criterios de soluci on Posible soluci on


import iic1103Packa ge .*; public class Cuenta { // Atributos private String nombre ; private String apellido ; private String RUT ; private String clave ; private int [] depositos ; private int [] giros ; /* * Constructor * @param nuevoNombre el nombre de la persona * @param nuevoApellido el apellido de la persona * @param nuevoRUTel RUT de la persona * @param nuevaClave la clave de la persona

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

49

* @param cantMaxla cantidad maxima de giros y depositos */ public Cuenta ( String nuevoNombre , String nuevoApellido , String nuevoRUT , String nuevaClave , int cantMax ) { nombre = nuevoNombre ; apellido = nuevoApellido ; RUT = nuevoRUT ; clave = nuevaClave ; depositos = new int [ cantMax ]; giros = new int [ cantMax ]; for ( int i = 0; i < cantMax ; i ++) { depositos [ i ] = -1; } for ( int i = 0; i < cantMax ; i ++) { giros [ i ] = -1; } } public String getNombre () { return nombre ; } public String getApellido () { return apellido ; } public String getRUT () { return RUT ; } public String getClave () { return clave ; } /* * Agrega un deposito a la lista * @param monto el deposito * @return true si pudo , false si no pq estaba llena */ public boolean a g re ga rD e po si t o ( int monto ) { // Buscamos espacio desocupado int i ; for ( i = 0; i < depositos . length ; i ++) { if ( depositos [ i ] == -1) { break ; } } // Revisa que no se pase del maximo if ( i < depositos . length ) { depositos [ i ] = monto ; return true ; } else { return false ; } } /* * Agrega un giro a la lista * @param monto el giro * @return true si pudo , false si no pq estaba llena */ public boolean agregarGiro ( int monto ) { // Buscamos espacio desocupado int i ; for ( i = 0; i < giros . length ; i ++) { if ( giros [ i ] == -1) { break ; } } // Revisa que no se pase del maximo if ( i < giros . length ) { giros [ i ] = monto ; return true ; } else { return false ; } } /* * Calcula el total de depositos * @return */ public int tota lDeposi tos () {

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

50

int total = 0; for ( int i = 0; i < depositos . length ; i ++) { if ( depositos [ i ] == -1) { break ; } else { total += depositos [ i ]; } } return total ; } /* * Calcula el total de giros * @return */ public int totalGiros () { int total = 0; for ( int i = 0; i < giros . length ; i ++) { if ( giros [ i ] == -1) { break ; } else { total += giros [ i ]; } } return total ; } /* * Calcula el saldo en la cuenta * @return */ public int saldo () { return total Deposit os () - totalGiros (); } /* * Muestra toda la informacion de la cuenta */ public void mostrarTodo () { // Depositos String mensaje = " Depositos de " + nombre + " " + apellido ; for ( int i = 0; i < depositos . length ; i ++) { if ( depositos [ i ] != -1) { mensaje += " \ n * " + depositos [ i ]; } } mensaje += " \ n Total : " + totalD epositos (); // Giros mensaje += " \ n \ nGiros de " + nombre + " " + apellido ; for ( int i = 0; i < giros . length ; i ++) { if ( giros [ i ] != -1) { mensaje += " \ n * " + giros [ i ]; } } mensaje += " \ n Total : " + totalGiros (); // Saldo mensaje += " \ n \ nSaldo : " + saldo (); // Mostramos Usuario . mensaje ( mensaje ); } } import iic1103Packa ge .*; public class AdminCuentas { private Cuenta [] cuentas ; private int cantCuentas ; /* * Constructor * @param maxCant */ public AdminCuentas ( int maxCant ) { cuentas = new Cuenta [ maxCant ]; cantCuentas = 0; } /* * Agrega una nueva cuenta * @param nuevaCuenta * la cuenta a agregar a la lista * @return true si pudo , false si no habia espacio public boolean crearCuenta ( Cuenta nuevaCuenta ) { if ( cantCuentas < cuentas . length ) { cuentas [ cantCuentas ++] = nuevaCuenta ; return true ; } else {

*/

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

51

return false ; } } /* * Muestra las cuentas existentes public void verCuentas () { String mensaje = " " ; for ( int i = 0; i < cantCuentas ; mensaje += " \ n " + ( i + 1) + " ) + cuentas [ i ]. getApellido () } Usuario . mensaje ( mensaje ); } */ i ++) { " + cuentas [ i ]. getNombre () + " " + " - " + cuentas [ i ]. getRUT ();

/* * Valida si un RUT y clave son validos , y retorna la cuenta asociada * @param RUT el rut a revisar * @param clave la clave a revisar * @return un objeto de tipo Cuenta */ public Cuenta getCuenta ( String RUT , String clave ) { // Buscamos clave y RUT for ( int i = 0; i < cantCuentas ; i ++) { if ( cuentas [ i ]. getRUT (). equals ( RUT ) && cuentas [ i ]. getClave (). equals ( clave )) { return cuentas [ i ]; } } // No encontramos return null ; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

52

Problema 17: Administraci on Biblioteca


Enunciado Debe implementar un programa que simule un sistema administraci on de una biblioteca. Se le pide implementar dos clases: SistemaBiblioteca y Libro. La clase SistemaBiblioteca consistir a en un sistema simple de administraci on de una biblioteca, y la clase Libro contendr a informaci on espec ca sobre un libro dado. Adem as, existir a una tercera clase, InterfazUsuario, que contendr a el main del programa, y que ya vendr a implementada. En particular, la clase Libro debe cumplir con lo siguiente: Debe almacenar el nombre y autor del libro como Strings. Debe almacenar el c odigo ISBN del libro como String. Debe almacenar el a no del libro como entero.

Debe almacenar la cantidad de copias existentes como entero.

Debe almacenar un arreglo de enteros de largo 7, donde cada posici on indica un d a de la semana, empezando por el d a lunes en la posici on 0. El valor almacenado en cada posici on indica la cantidad de copias del libro reservadas para ese d a de la pr oxima semana (los libros deben ser reservados de una semana para otra). Adem as, la clase Libro debe tener los siguientes m etodos: public Libro(String nuevoNombre, String nuevoAutor, String nuevoISBN, int nFecha, int nCopias): permite crear un nuevo libro, recibiendo como par ametros el nombre, autor, ISBN, a no y cantidad de copias del libro. No es necesario validar el formato del c odigo ISBN; cualquier String ser a aceptado como v alido. Se asumir a que no se crear an dos libros distintos con el mismo c odigo ISBN. public String getAutor(): retorna un String con el nombre del autor del libro. public String getNombre(): retorna un String con el nombre del libro. public String getISBN(): retorna un String con el c odigo ISBN. public int getFecha(): retorna un entero con el a no del libro.

public int getCantidadCopias(): retorna un entero con la cantidad de copias del libro.

public String getInfo(): retorna un String con toda la informaci on del libro, de la forma: Autor: X Nombre: Y A no: Z ISBN: N Copias: M, reemplazando X, Y, Z , N, M por lo que corresponda. public int getReservas(int cuando): recibe como par ametro un entero entre 1 y 7 que indica las reservas de qu e d a se quiere revisar, y retorna las reservas de ese d a. public boolean reservarCopia(int cuando): recibe como par ametro un entero entre 1 y 7 indicando para qu e d a de la pr oxima semana se quiere reservar un libro. Si quedan copias disponibles (no reservadas), debe aumentar la cantidad de copias reservadas para el d a indicado. Por ejemplo, si el par ametro es 1, indica que se quiere reservar una copia para el d a lunes, que es el primer lugar en el arreglo; por lo tanto, si quedan copias sin reservas se debe aumentar el valor en ese lugar del arreglo y retornar true; si no, retorna false. Debe asumir que los libros son reservados para la semana siguiente, y siempre todos son devueltos el lunes de la siguiente semana a primera hora, por lo que en cada semana se pueden reservar todas las copias de cada libro.

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

53

Por otro lado, la clase SistemaBiblioteca debe cumplir con lo siguiente: Debe almacenar una lista de libros en un arreglo, que corresponder an a los libros existentes en la biblioteca. Debe almacenar la cantidad de libros ya guardados en la lista. Adem as, la clase SistemaBiblioteca debe tener los siguientes m etodos: public SistemaBiblioteca(int tamanoBiblioteca): recibe como par ametro un entero que indica la capacidad de la biblioteca; es decir, cu antos libros puede almacenar como m aximo. public boolean agregarLibro(Libro nuevoLibro): recibe como par ametro un objeto de tipo Libro, y lo agrega a lista de libros de la biblioteca si existe un lugar disponible; si est a llena, no hace nada. No es necesario que valide si ya existe un libro con el mismo ISBN; se asume que esto no suceder a. Retorna true si lo pudo agregar, false si no pudo por estar llena. public Libro[] buscarLibroPorAutor(String autor): recibe como par ametro un String con el nombre de un autor, y busca todos los libros con ese nombre en la biblioteca. Retorna un arreglo de Libros, con todos los libros que cumplan con lo pedido. public Libro buscarLibroPorISBN(String ISBN): recibe como par ametro un String con el c odigo ISBN, y busca ese libro en la biblioteca. Retorna el Libro que cumpla con lo pedido (En la biblioteca todos los libros tienen distinto ISBN). Si no encuentra ning un libro con ese ISBN retorna null. public boolean reservarLibro(String ISBN, int dia): recibe como par ametro un String con un c odigo ISBN, y un n umero entero entre 1 y 7 indicando para qu e d a reservarlo (1 lunes, 2 martes, etc.). Busca ese libro en la biblioteca, e intenta reservarlo; si puede, retorna true; si no, retorna false. La clase InterfazUsuario, que contiene el main del programa, vendr a viene ya implementada y se muestra a continuaci on.
import iic1103Packa ge .*; public class I nt er fa z Us ua r io { public static void main ( String [] args ) { // Crea sistema int capacidad = Usuario . entero ( " Ingrese la capacidad maxima de la bilioteca ( mayor o igual a 4): " ); Si ste maBi b l i o t e c a biblio = new S i s t e m a B i b l i o t e c a ( capacidad ); // Libros biblio . agregarLibro ( new Libro ( " La Metamorfosis " , " Franz Kafka " , " 12 " , 1915 , 2)); biblio . agregarLibro ( new Libro ( " El Salto " , " Pepe Palote " , " 13 " , 1915 , 2)); biblio . agregarLibro ( new Libro ( " El Juicio " , " Franz Kafka " , " 14 " , 1925 , 1)); biblio . agregarLibro ( new Libro ( " El Juicio " , " Roberto Gomez " , " 15 " , 1990 , 3)); // Menu boolean salir = false ; while (! salir ) { int opcion = Usuario . entero ( " Elija una opcion :\ n (1) Agregar libro " + " \ n (2) Buscar libro \ n (3) Reservar libro \ n (4) Ver reservas \ n (5) Salir " ); if ( opcion == 1) { // Obtenemos datos String nombre = Usuario . texto ( " Ingrese el nombre del nuevo libro : " ); String autor = Usuario . texto ( " Ingrese el autor del nuevo libro : " ); String ISBN = Usuario . texto ( " Ingrese el codigo ISBN del nuevo libro : " ); int fecha = Usuario . entero ( " Ingrese el anio del nuevo libro : " ); int copias = Usuario . entero ( " Ingrese la cantidad de copias del libro : " ); Libro nuevoLibro = new Libro ( nombre , autor , ISBN , fecha , copias ); // Agregamos if ( biblio . agregarLibro ( nuevoLibro )) { Usuario . mensaje ( " Libro agregado . " ); } else { Usuario . mensaje ( " Libro no fue agregado . " ); } } else if ( opcion == 2) { // Pedimos tipo de busqueda y buscamos

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

54

String m e n s a j e R e s u l t a d o s = " Resultados :\ n " ; int subOpcion = Usuario . entero ( " Elija tipo de busqueda : " + " \ n (1) Buscar por autor \ n (2) Buscar por ISBN " ); if ( subOpcion == 1) { // Caso busqueda por autor ; recibe un arreglo String autor = Usuario . texto ( " Ingrese el autor a buscar : " ); Libro [] resultados = biblio . b u s c a r L i b r o P o r A u t o r ( autor ); // Agrega todos los resultados a string for ( int i = 0; i < resultados . length ; i ++) { m e n s a j e R e s u l t a d o s += " - " + resultados [ i ]. getInfo () + " \ n " ; } // Avisamos si no encontro nada if ( resultados . length == 0) { m e n s a j e R e s u l t a d o s += " No se encontraron libros del autor " + autor ; } } else { // Caso busqueda por ISBN ; recibe 1 resultado String ISBN = Usuario . texto ( " Ingrese el ISBN a buscar : " ); Libro resultado = biblio . b u s c a r L i b r o P o r I S B N ( ISBN ); // Agrega resultado a mensaje : if ( resultado != null ) { m e n s a j e R e s u l t a d o s += " - " + resultado . getInfo () + " \ n " ; } else { m e n s a j e R e s u l t a d o s += " No se encontro libro con el ISBN " + ISBN ; } } // Mostramos Usuario . mensaje ( m e n s a j e R e s u l t a d o s ); } else if ( opcion == 3) { // Obtenemos info String ISBN = Usuario . texto ( " Ingrese el codigo ISBN del libro a reservar : " ); int dia = Usuario . entero ( " Ingrese para que dia de la proxima semana " + " lo quiere reservar (1 -7): " ); // Reservamos if ( biblio . reservarLibro ( ISBN , dia )) { Usuario . mensaje ( " Libro reservado " ); } else { Usuario . mensaje ( " Libro no reservado " ); } } else if ( opcion == 4) { // Obtenemos libro String ISBN = Usuario . texto ( " Ingrese el codigo ISBN del libro a revisar : " ); Libro lib = biblio . b u s c a r L i b r o P o r I S B N ( ISBN ); if ( lib != null ) { // Libro encontrado , muestra las reservas String m e ns aj eR e se rv a s = " Las reservas son :\ n " ; for ( int i = 1; i <= 7; i ++) { m en sa je R es er va s += " Dia " + i + " : " + lib . getReservas ( i ) + " \ n " ; } Usuario . mensaje ( m en sa j eR es er v as ); } else { Usuario . mensaje ( " Libro no encontrado " ); } } else if ( opcion == 5) { salir = true ; } } } }

Criterios de soluci on Posible soluci on


public class Libro { // Valores del libro private String nombre ; private String autor ; private String ISBN ; private int fecha ; private int copias ; // Arreglo con reservas int [] reservas = new int [7];

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

55

/* * Constructor de la clase * @param nuevoNombre el nombre del libro * @param nuevoAutor el autor * @param nuevoISBN el codigo ISBN * @param nFecha el anio del libro * @param nCopias la cantidad de copias del libro */ public Libro ( String nuevoNombre , String nuevoAutor , String nuevoISBN , int nFecha , int nCopias ) { nombre = nuevoNombre ; autor = nuevoAutor ; ISBN = nuevoISBN ; fecha = nFecha ; copias = nCopias ; // Inicializamos las reservas en cero for ( int i = 0; i < reservas . length ; i ++) { reservas [ i ] = 0; } } // Retorna autor public String getAutor () { return autor ; } // Retorna nombre public String getNombre () { return nombre ; } // Retorna ISBN public String getISBN () { return ISBN ; } // Retorna la fecha public int getFecha () { return fecha ; } // Retorna la cantidad de copias public int g e t C a n t i d a d C o p i a s () { return copias ; } // Retorna la informacion del libro en un string public String getInfo () { return " Autor : " + autor + " - Nombre : " + nombre + " - Anio : " + fecha + " - ISBN : " + ISBN + " - Copias : " + copias ; } /* * Reserva una copia del libro para un dia especifico * @param cuando el dia pedido * @return */ public boolean reservarCopia ( int cuando ) { // Revisa cuantas copias hay reservadas int reservadas = 0; for ( int i = 0; i < reservas . length ; i ++) { reservadas += reservas [ i ]; } if (( reservadas < copias ) && ( cuando <= reservas . length )) { // Agregamos reserva reservas [ cuando - 1]++; return true ; } else { return false ; } } /* * Retorna la cantidad de reservas de un dia * @param cuando el dia pedido * @return */ public int getReservas ( int cuando ) { if ( cuando <= reservas . length ) { return reservas [ cuando - 1]; } else { return 0;

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

56

} } } public class S i s t e m a B i b l i o t e c a { // Biblioteca Libro [] listaLibros ; int numLibros ; /* * Constructor * @param ta m a n o B i b l i o t e c a la cantidad de libros maxima a almacenar */ public Si st e m a B i b l i o t e c a ( int t a m a n o B i b l i o t ec a ) { listaLibros = new Libro [ t a m a n o B i b li o t e c a ]; numLibros = 0; } /* * Agrega un libro a la biblioteca * @param nuevoLibro un libro nuevo * @return si pudo o no agregar un libro */ public boolean agregarLibro ( Libro nuevoLibro ) { if ( numLibros < listaLibros . length ) { listaLibros [ numLibros ++] = nuevoLibro ; return true ; } else { return false ; } } /* * Busca libro por autor * @param nombre el nombre del libro * @return */ public Libro [] b u s c a r L i b r o P o r A u t o r ( String autor ) { // Primero contamos la cantidad de resultados int numResultados = 0; for ( int i = 0; i < numLibros ; i ++) { if ( listaLibros [ i ]. getAutor (). equals ( autor )) { numResultados ++; } } // Almacena los resultados Libro [] resultados = new Libro [ numResultados ]; int pos = 0; for ( int i = 0; i < numLibros ; i ++) { if ( listaLibros [ i ]. getAutor (). equals ( autor )) { resultados [ pos ++] = listaLibros [ i ]; } } // Retorna return resultados ; } /* * Busca libro por ISBN * @param ISBN el ISBN del libro * @return un Libro con el ISBN indicado , o null si no habia */ public Libro b u s c a r L i b r o P o r I S B N ( String ISBN ) { // Primero contamos la cantidad de resultados Libro buscado = null ; for ( int i = 0; i < numLibros ; i ++) { if ( listaLibros [ i ]. getISBN (). equals ( ISBN )) { buscado = listaLibros [ i ]; } } // Retorna lo encontrado return buscado ; } /* * Reserva un libro . * @param ISBN el codigo del libro * @param dia el dia a reservar * @return */ public boolean reservarLibro ( String ISBN , int dia ) { Libro libro = b u s c a r L i b r o P o r I S B N ( ISBN ); if ( libro . reservarCopia ( dia )) { return true ; } else { return false ; }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

57

} }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

58

Problema 18: Administraci on Regalos Novios


Enunciado Debe implementar un programa que simule un sistema de administraci on de una lista de regalos de novios. Se le pide implementar dos clases: AdminNovios y Novios. La clase AdminNovios consistir a en un sistema simple de administraci on de listas de regalos de novios; la clase Novios, en informaci on sobre una pareja de novios. Adem as, existir an dos clases m as que vendr an implementadas: InterfazUsuario, que contendr a el main del programa, y Regalo, que contendr a informaci on espec ca sobre un regalo dado. La clase Novios debe cumplir con lo siguiente: Debe almacenar el nombre del novio y el nombre de la novia como Strings. Debe tener dos listas de Regalos: una lista de Regalos no comprados, y una lista de regalos ya comprados (ambas de tipo arreglo de Regalos). Debe tener dos enteros, almacenando la cantidad de regalos no comprados, y la cantidad de regalos comprados (es decir, la cantidad de objetos Regalos en cada arreglo). Adem as, la clase Novios debe tener los siguientes m etodos: public Novios(String nuevoNovio, String nuevaNovia, int cantMaxima): permite crear un nuevo elemento Novios, recibiendo como par ametros el nombre del novio, el nombre de la novia, y la cantidad m axima de regalos que podr an registrar. public String getNombreNovio(): retorna el nombre del novio. public String getNombreNovia(): retorna el nombre de la novia.

public boolean agregarRegalo(Regalo nuevoRegalo): recibe como par ametro un objeto de tipo Regalo. Revisa si ya est a en la lista de no comprados; si no est a, lo agrega a la lista; si est a, no hace nada y retorna falso. Retorna true si lo pudo agregar, false si no pudo por no haber m as espacio. public void mostrarRegalosNoComprados(String categoria): recibe como par ametro un String indicando una categor a, y muestra en pantalla un mensaje indicando toda la informaci on de los regalos no comprados correspondientes a esa categor a (nombre, categor a). Si la categor a es un String vac o (), muestra todos los regalos no comprados. public void mostrarRegalosYaComprados(String categoria): recibe como par ametro un String indicando una categor a, y muestra en pantalla un mensaje indicando toda la informaci on de los regalos ya comprados correspondientes a esa categor a (nombre, categor a). Si la categor a es un String vac o (), muestra todos los regalos ya comprados. public boolean comprarRegalo(String nombreRegalo): recibe como par ametro un String con el nombre de un Regalo. Revisa si existe ese regalo en la lista de no comprados; si no est a, retorna false. Si est a, lo pasa a la lista de ya comprados. Posteriormente, mueve los Regalos en la lista de no comprados en lugares siguientes al comprado un lugar hacia abajo, para que queden continuos en el arreglo (y se elimine el comprado de la lista de no comprados). Finalmente, retorna true si pudo hacer todo, o false si no. Ayuda: puede que le sirva crear un m etodo m as o menos gen erico para buscar la posici on de algo en un arreglo, como m etodo privado en la clase Novios, para facilitarle el desarrollo de los otros m etodos y reescribir menos c odigo. Por otro lado, la clase AdminNovios debe cumplir con lo siguiente: IIC1103 Cap tulo 7: Ordenaci on y B usqueda 59

Debe almacenar un arreglo de Novios.

Debe almacenar la cantidad de objetos Novios almacenados en el arreglo. Adem as, la clase AdminNovios debe tener los siguientes m etodos: public AdminNovios(int cantMaxima): recibe como par ametro un entero que indica la cantidad m axima de Novios permitida; es decir, cu antos objetos Novios puede almacenar como m aximo. public boolean agregarNovio(Novios nuevoNovio): recibe como par ametro un objeto de tipo Novio, y lo agrega a lista de novios si existe un lugar disponible; si est a lleno, no hace nada. Retorna true si lo pudo agregar, false si no pudo por estar lleno. public Novios[] buscarNovios(String nombre): recibe como par ametro un String con el nombre de un novio o novia, y busca todos los novios con esa informaci on en el arreglo. Retorna un arreglo con los Novios encontrados. La clase Regalo y la clase InterfazUsuario vienen ya implementadas y se describen a continuaci on.
public class Regalo { private String nombre ; private String categoria ; /* * Constructor * @param nuevoNombre el nombre del producto * @param nuevaCa tegoria la categoria del producto */ public Regalo ( String nuevoNombre , String nu evaCateg oria ) { nombre = nuevoNombre ; categoria = nuevaC ategoria ; } // Retorna nombre public String getNombre () { return nombre ; } // Retorna categoria public String getCategoria () { return categoria ; } } import iic1103Packa ge .*; public class I nt er fa z Us ua r io { public static void main ( String [] args ) { // Crea sistema int capacidad = Usuario . entero ( " Ingrese la capacidad maxima de novios " + " ( mayor o igual a 3): " ); AdminNovios admin = new AdminNovios ( capacidad ); // Crea los novios y regalos predefinidos Novios novio1 = new Novios ( " Juan Perez " , " Juana Garrido " , 10); novio1 . agregarRegalo ( new Regalo ( " mesa " , " muebles " )); novio1 . agregarRegalo ( new Regalo ( " sabanas " , " ropa de cama " )); admin . agregarNovio ( novio1 ); Novios novio2 = new Novios ( " Pepe Botella " , " Juana la Loca " , 10); novio2 . agregarRegalo ( new Regalo ( " lampara " , " adornos " )); novio2 . agregarRegalo ( new Regalo ( " sillas " , " muebles " )); admin . agregarNovio ( novio2 ); Novios novio3 = new Novios ( " Juan Perez " , " Cristina Perl " , 10); novio3 . agregarRegalo ( new Regalo ( " sillas " , " muebles " )); novio3 . agregarRegalo ( new Regalo ( " mesa " , " muebles " )); admin . agregarNovio ( novio3 ); // Menu boolean salir = false ; while (! salir ) { // Muestra menu y obtiene opcion int opcion = Usuario . entero ( " Elija una opcion :\ n (1) Agregar novios " + " \ n (2) Ver regalos \ n (3) Agregar regalo \ n (4) Comprar regalo \ n (5) Salir " ); if ( opcion == 1) { // Agregar novios // Obtenemos datos

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

60

String novio = Usuario . texto ( " Ingrese el nombre del novio : " ); String novia = Usuario . texto ( " Ingrese el nombre de la novia : " ); Novios nuevoNovio = new Novios ( novio , novia , 10); // Agregamos if ( admin . agregarNovio ( nuevoNovio )) { Usuario . mensaje ( " Novios agregados . " ); } else { Usuario . mensaje ( " Novios no fueron agregados . " ); } } else if ( opcion == 2) { // Ver regalos // Mostramos novios y permite elegir String nombre = Usuario . texto ( " Ingrese el nombre del novio o novia : " ); Novios [] resultados = admin . buscarNovios ( nombre ); int numNovio = elegirNovios ( admin , resultados ); // Si es valido if ( numNovio != -1) { // Obtenemos categoria String categoria = Usuario . texto ( " Ingrese una categoria a buscar " + " ( o no ingrese nada para ver todos ): " ); if ( categoria == null ) { categoria = " " ; } // Mostramos resultados [ numNovio ]. m o s t r a r R e g a l o s N o C o m p r a d o s ( categoria ); resultados [ numNovio ]. m o s t r a r R e g a l o s Y a C o m p r a d o s ( categoria ); } } else if ( opcion == 3) { // Agregar regalo // Obtenemos novios String nombre = Usuario . texto ( " Ingrese el nombre del novio o novia : " ); Novios [] resultados = admin . buscarNovios ( nombre ); int numNovio = elegirNovios ( admin , resultados ); if ( numNovio != -1) { // Buscamos info del nuevo regalo String nombreRegalo = Usuario . texto ( " Ingrese el nombre del nuevo regalo : " ); String catRegalo = Usuario . texto ( " Ingrese categoria del nuevo regalo : " ); // Agregamos regalo boolean exito = resultados [ numNovio ] . agregarRegalo ( new Regalo ( nombreRegalo , catRegalo )); if ( exito ) { Usuario . mensaje ( " Regalo agregado " ); } else { Usuario . mensaje ( " Regalo no agregado " ); } } } else if ( opcion == 4) { // Comprar regalos // Obtenemos novios String nombre = Usuario . texto ( " Ingrese el nombre del novio o novia : " ); Novios [] resultados = admin . buscarNovios ( nombre ); int numNovio = elegirNovios ( admin , resultados ); if ( numNovio != -1) { // Mostramos regalos resultados [ numNovio ]. m o s t r a r R e g a l o s N o C o m p r a d o s ( " " ); resultados [ numNovio ]. m o s t r a r R e g a l o s Y a C o m p r a d o s ( " " ); // Obtenemos info del regalo String nombreRegalo = Usuario . texto ( " Ingrese el nombre del regalo a comprar : " ); // Compramos regalo if ( resultados [ numNovio ]. comprarRegalo ( nombreRegalo )) { Usuario . mensaje ( " Se compro regalo " + nombreRegalo + " a novios " + resultados [ numNovio ]. g etNombr eNovio () + " - " + resultados [ numNovio ]. g etNombr eNovia ()); } else { Usuario . mensaje ( " No se pudo comprar el regalo " + nombreRegalo + " a novios " + resultados [ numNovio ]. g etNombr eNovio () + " - " + resultados [ numNovio ]. g etNombr eNovia ()); } } } else if ( opcion == 5) { // Salir salir = true ; } } } /* * Funcion usada para buscar novios , mostrar resultados , y elegir uno * @param admin

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

61

* @return */ private static int elegirNovios ( AdminNovios admin , Novios [] resultados ) { // Mostramos String me n s a j e R e s u l t a d o s = " Novios encontrados :\ n " ; for ( int i = 0; i < resultados . length ; i ++) { me nsa je R e s u l t a d o s += ( i + 1) + " ) " + resultados [ i ]. getNo mbreNovi o () + " - " + resultados [ i ]. getNo mbreNovi a () + " \ n " ; } int numNovio = Usuario . entero ( m e n s a j e R e s u l t a d o s + " \ nElija un novio a revisar de los anteriores (0 para volver ): " ); // Si es valido , retorna el numero if ( numNovio > 0 && numNovio <= resultados . length ) { return numNovio - 1; } else { return -1; } } }

Criterios de soluci on Posible soluci on


import iic1103Packa ge .*; public class Novios { // Info de novios private String nombreNovio ; private String nombreNovia ; // Info private private private private de regalos Regalo [] noComprados ; Regalo [] yaComprados ; int ca n tN oC o mp ra do s = 0; int ca n tY aC o mp ra do s = 0;

/* * Constructor * @param nuevoNovio nombre del novio * @param nuevaNovia nombre de la novia * @param cantMaxima cantidad maxima de regalos */ public Novios ( String nuevoNovio , String nuevaNovia , int cantMaxima ) { nombreNovio = nuevoNovio ; nombreNovia = nuevaNovia ; noComprados = new Regalo [ cantMaxima ]; yaComprados = new Regalo [ cantMaxima ]; } // Retorna el nombre del novio public String getNom breNovi o () { return nombreNovio ; } // Retorna el nombre de la novia public String getNom breNovi a () { return nombreNovia ; } /* * Funcion generica para buscar un regalo por nombre en un arreglo * @param nombreRegalo el nombre del regalo * @param arreglo el arreglo donde se busca * @param cantArreglo la cantidad de elementos en el arreglo * @return la posicion donde estaba */ private int p osicion Regalo ( String nombreRegalo , Regalo [] arreglo , int cantArreglo ) { // Busca si ya esta int pos = -1; for ( int i = 0; i < cantArreglo ; i ++) { if ( arreglo [ i ]. getNombre (). equals ( nombreRegalo )) { pos = i ; break ; } } // Retorna return pos ;

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

62

} /* * Agrega un regalo a la lista de no comprados * @param nuevoRegalo el nuevo regalo * @return si lo agrego o no */ public boolean agregarRegalo ( Regalo nuevoRegalo ) { // Busca si ya esta int pos = posicio nRegalo ( nuevoRegalo . getNombre () , noComprados , cantN oC o mp ra d os ); // Revisa accion if ( pos == -1) { // No estaba ; lo agrega if ( can tN oC o mp ra do s < noComprados . length ) { noComprados [ ca n tN oC om p ra do s ++] = nuevoRegalo ; } else { return false ; } } else { return false ; } // Exito return true ; } /* * Muestra los regalos no comprados */ public void m o s t r a r R e g a l o s N o C o m p r a d o s ( String categoria ) { String mensaje = " Regalos no comprados :\ n " ; for ( int i = 0; i < c a nt No C om pr ad o s ; i ++) { if ( noComprados [ i ]. getCategoria (). equals ( categoria ) || ( categoria . equals ( " " ))){ mensaje += " - " + noComprados [ i ]. getNombre () + " , categoria " + noComprados [ i ]. getCategoria () + " \ n " ; } } Usuario . mensaje ( mensaje ); } /* * Muestra los regalos no comprados */ public void m o s t r a r R e g a l o s Y a C o m p r a d o s ( String categoria ) { String mensaje = " Regalos ya comprados :\ n " ; for ( int i = 0; i < c a nt Ya C om pr ad o s ; i ++) { if ( yaComprados [ i ]. getCategoria (). equals ( categoria ) || ( categoria . equals ( " " ))) { mensaje += " - " + yaComprados [ i ]. getNombre () + " , categoria " + yaComprados [ i ]. getCategoria () + " \ n " ; } } Usuario . mensaje ( mensaje ); } /* * Compra un regalo , pasandolo de la lista de no comprados a la otra * @param nombreRegalo * @return true si lo compro , false si no existia o si estaba llena la otra * lista ( de comprados ) */ public boolean comprarRegalo ( String nombreRegalo ) { // Busca el regalo int posEn N o C o m p r a d o s = p osicion Regalo ( nombreRegalo , noComprados , cantN oC o mp ra d os ); if ( posEn N o C o m p r a d o s == -1) { return false ; } else { // Lo pasamos a la otra lista if ( can tY aC o mp ra do s < yaComprados . length ) { yaComprados [ ca n tY aC om p ra do s ++] = noComprados [ p o s E n N o C o m p r a d o s ]; } else { return false ; } // Corremos objetos en lista de no comprados para borrar el movido for ( int i = p o s E n N o C o m p r a d o s ; i < ca nt N oC om p ra do s - 1; i ++) { noComprados [ i ] = noComprados [ i + 1]; } cantNoComprados - -; return true ; } } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

63

public class AdminNovios { private Novios [] listaNovios ; private int cantNovios = 0; /* * Constructor * @param cantMaxima la cantidad de novios maxima del arreglo */ public AdminNovios ( int cantMaxima ) { listaNovios = new Novios [ cantMaxima ]; } /* * Agrega un novio a la lista * @param nuevoNovio los novios * @return true si pudo , false si no */ public boolean agregarNovio ( Novios nuevoNovio ) { // Lo agrega if ( cantNovios < listaNovios . length ) { listaNovios [ cantNovios ++] = nuevoNovio ; return true ; } else { return false ; } } /* * Busca todos los novios o novias con el nombre dado * @param nombre * @return */ public Novios [] buscarNovios ( String nombre ) { // Primero contamos los resultados int cantRe sultados = 0; for ( int i = 0; i < cantNovios ; i ++) { if ( listaNovios [ i ]. getNom breNovio (). equals ( nombre ) || listaNovios [ i ]. getNomb reNovia (). equals ( nombre )) { cantResultad os ++; } } // Busca los novios o novias con nombre indicado int pos = 0; Novios [] resultados = new Novios [ cantResu ltados ]; for ( int i = 0; i < cantNovios ; i ++) { if ( listaNovios [ i ]. getNom breNovio (). equals ( nombre ) || listaNovios [ i ]. getNomb reNovia (). equals ( nombre )) { resultados [ pos ++] = listaNovios [ i ]; } } // Retorno return resultados ; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

64

Problema 19: Administraci on Notas


Enunciado Debe implementar un programa que simule un sistema de administraci on de notas. Se le pide implementar dos clases: AdminEstudiantes, y Estudiante. La clase AdminEstudiantes consistir a en un sistema simple de administraci on de informaci on de estudiantes; la clase Estudiante, consistir a en informaci on detallada sobre un estudiante en particular y sus notas. Adem as, existir a una tercera clase, InterfazUsuario, que contendr a el main del programa, y que vendr a implementada. Estudiante: Debe tener los siguientes atributos: El nombre del estudiante en un String. El apellido del estudiante en un String.

Un c odigo del curso en que est a en un String (asuma que un alumno esta solamente en un curso). Un arreglo de doubles con las notas del estudiante para el curso en que est a. Un arreglo de enteros con la ponderaci on de cada una de las notas almacenadas en el arreglo anterior. Adem as, la clase Estudiante debe tener los siguientes m etodos: public Estudiante(String nuevoNombre, String nuevoApellido, String nuevoCodigo, int cantNotas): El constructor crea un nuevo objeto Estudiante, recibiendo como par ametros el nombre del estudiante, el apellido del estudiante, el c odigo del curso y la cantidad m axima de notas que tendr a. Inicializa con un 0 en todas las notas, y en 0 todas las ponderaciones y ja los valores de los atributos. public String getNombre(): retorna el nombre del estudiante. public String getApellido(): retorna el apellido del estudiante.

public String getCodigo(): retorna el c odigo del curso del estudiante.

public void setNota(int numNota, double nota): recibe como par ametro un entero entre 1 y la cantidad m axima de notas (es decir indica si es la primera, segunda, tercera nota, etc. hasta la cantidad m axima de notas). El otro par ametro es un double conteniendo la nota en s . La nota se almacena en el arreglo (recordar que en los arreglos, los lugares parten de 0). Debe validar si el par ametro recibido est a en el rango correcto. public void setPonderacion(int numPonderacion, int ponderacion): recibe como par ametro un entero entre 1 y la cantidad m axima de notas (indicando si es la ponderaci on de la primera, segunda, tercera, etc. ponderaci on), y un entero con el porcentaje de ponderaci on de la nota. La ponderaci on se almacena en el arreglo (recordar que en los arreglos, los lugares parten de 0). Debe validar si el par ametro recibido est a en el rango correcto. public double calcularPromedio(): calcula el promedio ponderado de las notas del estudiante, y retorna un double con este promedio. public double getMejorNota(): busca en las notas almacenadas (sin ponderar), y retorna un double con la mejor nota obtenida. public void mostrarNotas(): muestra en pantalla un mensaje indicando cada nota y su ponderaci on; tambi en muestra el promedio y la mejor nota. AdminEstudiantes: Debe tener los siguientes atributos: IIC1103 Cap tulo 7: Ordenaci on y B usqueda 65

Un arreglo de objetos de tipo Estudiante (almacena Estudiantes).

Un entero indicando con la cantidad de objetos de tipo Estudiante actualmente almacenados en el arreglo. Adem as, la clase AdminEstudiantes debe tener los siguientes m etodos: public AdminEstudiantes(int maxEstudiantes): Constructor, recibe como par ametro un entero que indica la cantidad m axima de Estudiantes permitida; es decir, cu antos objetos Estudiante puede almacenar como m aximo. public boolean agregarEstudiante(Estudiante nuevoEstudiante): recibe como par ametro un objeto de tipo Estudiante, y lo agrega al arreglo de estudiantes si existe un lugar disponible; si est a lleno, no hace nada. Retorna true si pudo agregar al estudiante y false si no pudo por estar lleno. public void verEstudiantes(): muestra un mensaje en pantalla con una lista de todos los estudiantes almacenados en el arreglo, indicando, para cada uno, su posici on en la lista (partiendo de 1); y su Apellido, Nombre separados por ,. Por ejemplo, para el que est a en el lugar 0 mostrar a 1) Apellido, Nombre, en la siguiente l nea el segundo, luego el tercero, etc. public double calcularPromedioCurso(String codigoCurso): recibe como par ametro un String con el c odigo de un curso, y calcula el promedio simple entre los promedios ponderados de todos los alumnos pertenecientes a ese curso. Retorna un double con el promedio. Si no se encuentra ning un estudiante de ese curso, deber a retornar -1. public Estudiante[] buscarEstudiante(String nombre): recibe como par ametro un String, que puede contener el nombre o el apellido, y lo busca en la lista. Debe ser no sensible a las may usculas; es decir, debe encontrar al estudiante sin importar si el String buscado (nombre o apellido) tienen may usculas o min usculas. Retorna un arreglo de objetos de tipo Estudiante con TODOS los estudiantes encontrados cuyo nombre o apellido sean iguales al String nombre. El tama no del nuevo arreglo debe ser igual a la cantidad de estudiantes encontrados cuyo nombre o apellido sean iguales al String nombre. La clase InterfazUsuario, que contiene el main del programa, ya est a implementada y se detalla a continuaci on.
import iic1103Packa ge .*; public class I nt er fa z Us ua r io { public static void main ( String [] args ) { // Crea sistema int capacidad = Usuario . entero ( " Ingrese la capacidad maxima de estudiantes " + " a soportar ( mayor o igual a 3): " ); AdminEstu d i a n t e s admin = new A d m in E s t u d i a n t e s ( capacidad ); // Crea los estudiantes predefinidos : Estudiante est1 = new Estudiante ( " Matias " , " Recabarren " , " IIC1102 " , 4); est1 . setNota (1 , 6.2); est1 . setPondera cion (1 , 20); est1 . setNota (2 , 5.2); est1 . setPondera cion (2 , 40); est1 . setNota (3 , 4.2); est1 . setPondera cion (3 , 20); est1 . setNota (4 , 4.2); est1 . setPondera cion (4 , 20); admin . ag r e g a r E s t u d i a n t e ( est1 ); Estudiante est2 = new Estudiante ( " Ignacio " , " Baixas " , " IIC1102 " , 4); est2 . setNota (1 , 7); est2 . setPondera cion (1 , 25); est2 . setNota (2 , 6); est2 . setPondera cion (2 , 25); est2 . setNota (3 , 5); est2 . setPondera cion (3 , 25); est2 . setNota (4 , 4);

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

66

est2 . setPondera cion (4 , 25); admin . ag r e g a r E s t u d i a n t e ( est2 ); Estudiante est3 = new Estudiante ( " Ignacio " , " Osorio " , " IIC1103 " , 4); est3 . setNota (1 , 3.3); est3 . setPondera cion (1 , 30); est3 . setNota (2 , 2.5); est3 . setPondera cion (2 , 10); est3 . setNota (3 , 4); est3 . setPondera cion (3 , 50); est3 . setNota (4 , 3.9); est3 . setPondera cion (4 , 10); admin . ag r e g a r E s t u d i a n t e ( est3 ); // Menu boolean salir = false ; while (! salir ) { // Muestra menu y obtiene opcion int opcion = Usuario . entero ( " Elija una opcion :\ n (1) Ver estudiantes " + " \ n (2) Agregar estudiante \ n (3) Ver notas estudiante " + " \ n (4) Ver promedio curso \ n (5) Salir " ); if ( opcion == 1) { // Ver estudiantes admin . verEs tudiant es (); } else if ( opcion == 2) { // Agregar estudiante // Obtenemos datos String nombre = Usuario . texto ( " Ingrese el nombre del estudiante : " ); String apellido = Usuario . texto ( " Ingrese el apellido del estudiante : " ); String codigo = Usuario . texto ( " Ingrese el codigo del curso del estudiante : " ); Estudiante est = new Estudiante ( nombre , apellido , codigo , 4); // Pide 4 notas y sus ponderaciones for ( int i = 1; i <= 4; i ++) { double nota = Usuario . real ( " Ingrese la nota " + i + " del estudiante : " ); int ponderacion = Usuario . entero ( " Ingrese la ponderacion " + i + " del estudiante : " ); est . setNota (i , nota ); est . se tPonder acion (i , ponderacion ); } // Agregamos if ( admin . a g r e g a r E s t u d i a n t e ( est )) { Usuario . mensaje ( " Estudiante agregado . " ); } else { Usuario . mensaje ( " Estudiante no agregado . " ); } } else if ( opcion == 3) { // Ver notas estudiante // Obtenemos estudiante String nombre = Usuario . texto ( " Ingrese el nombre o apellido del estudiante : " ); Estudiante [] resultados = admin . b u s c a r E s t u d i a n t e ( nombre ); int posEstudiante = e l e gi r E s t u d i a n t e ( admin , resultados ); // Mostramos if ( posEstudiante != -1) { resultados [ posEstudiante - 1]. mostrarNotas (); } else { Usuario . mensaje ( " Estudiante no elegido . " ); } } else if ( opcion == 4) { // Ver promedio curso // Calculamos el promedio del curso String codigo = Usuario . texto ( " Ingrese el codigo del curso a revisar : " ); double promedio = admin . c a l c u l a r P r o m e d i o C u r s o ( codigo ); // Mostramos if ( promedio != -1) { Usuario . mensaje ( " Promedio del curso " + codigo + " : " + promedio ); } else { Usuario . mensaje ( " No hay estudiantes con notas en el curso . " ); } } else if ( opcion == 5) { // Salir salir = true ; } } } /* * Funcion usada para buscar estudiantes , mostrar resultados , y elegir uno * @param admin * @return un entero con el numero en el arreglo de resultados del * estudiante ( entre 1 y el total ) */ private static int e l e g i r E s t u d i a n t e ( A d m i n E s t u d i a n te s admin ,

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

67

Estudiante [] resultados ) { // Mostramos String me n s a j e R e s u l t a d o s = " Estudiantes encontrados :\ n " ; for ( int i = 0; i < resultados . length ; i ++) { me nsa je R e s u l t a d o s += ( i + 1) + " ) " + resultados [ i ]. getApellido () + " , " + resultados [ i ]. getNombre () + " \ n " ; } int posEstudiante = Usuario . entero ( m e n s a j e R e s u l t a d o s + " \ nElija un estudiante a revisar de los anteriores " + " (0 para volver ): " ); // Si es valido , retorna el numero if ( posEstudiante > 0 && posEstudiante <= resultados . length ) { return posEstudiante ; } else { return -1; } } }

Criterios de soluci on Posible soluci on


import iic1103Packa ge .*; public class Estudiante { private String nombre ; private String apellido ; private String codigoCurso ; private double [] notas ; private int [] ponderaciones ; /* * Constructor * @param nuevoNombre el nombre del estudiante * @param nuevoApellido el apellido del estudiante * @param nuevoCodigo el codigo del curso * @param cantNotas la cantidad de notas que tiene ese curso */ public Estudiante ( String nuevoNombre , String nuevoApellido , String nuevoCodigo , int cantNotas ) { nombre = nuevoNombre ; apellido = nuevoApellido ; codigoCurso = nuevoCodigo ; notas = new double [ cantNotas ]; ponderaciones = new int [ cantNotas ]; // Inicializamos las notas y ponderaciones en 0 for ( int i = 0; i < cantNotas ; i ++) { notas [ i ] = 0; ponderaciones [ i ] = 0; } } // Retorna el nombre public String getNombre () { return nombre ; } // Retorna el apellido public String getApellido () { return apellido ; } // Retorna el codigo public String getCodigo () { return codigoCurso ; } /* * Setea una nota * @param numNota el lugar de la nota , entre 1 y la cantidad maxima de notas * @param nota la nota a almacenar */ public void setNota ( int numNota , double nota ) { if ( numNota > 0 && numNota <= notas . length ) { notas [ numNota - 1] = nota ; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

68

/* * Setea una ponderacion * @param num Pondera cion el lugar de la ponderacion , entre 1 y la cantidad maxima de * notas * @param ponderacion la ponderaciona a almacenar , en porcentaje entero ( entre 0 y * 100) */ public void se tPonder acion ( int numPonderacion , int ponderacion ) { if ( numPonde racion > 0 && n umPonde racion <= ponderaciones . length ) { ponderaciones [ numPonde racion - 1] = ponderacion ; } } /* * Calcula el promedio ponderado de las notas del estudiante * @return un double con el promedio */ public double c a l cu l a r P r o m e d i o () { double promedio = 0; for ( int i = 0; i < notas . length ; i ++) { promedio += notas [ i ] * ponderaciones [ i ] / 100; } return promedio ; } /* * Busca la mejor nota * @return la nota mas alta , o -1 si todas son 0 */ public double getMejorNota () { double mejorNota = -1; for ( int i = 0; i < notas . length ; i ++) { if ( notas [ i ] > mejorNota ) { mejorNota = notas [ i ]; } } return mejorNota ; } /* * Muestra todas las notas y sus ponderaciones , mas el promedio y la mejor */ public void mostrarNotas () { // Agregamos las notas al mensaje String mensaje = " Notas del estudiante " + apellido + " , " + nombre ; for ( int i = 0; i < notas . length ; i ++) { mensaje += " \ nNota " + ( i + 1) + " : " + notas [ i ] + " ; Ponderacion : " + ponderaciones [ i ]; } // Agregamos promedio , peor y mejor mensaje += " \ nPromedio : " + c a l c u l ar P r o m e d i o (); mensaje += " \ nMejor : " + getMejorNota (); Usuario . mensaje ( mensaje ); } } import iic1103Packa ge .*; public class A d m i n E s t u d i a n t e s { private Estudiante [] estudiantes ; private int ca n tE st u di an te s ; /* * Constructor * @param maxEstu diantes la cantidad maxima de estudiantes soportada */ public Admi n E s t ud i a n t e s ( int maxEs tudiante s ) { estudiantes = new Estudiante [ maxE studian tes ]; cantEstudi an t es = 0; } /* * Agrega un estudiante a la lista * @param n ue vo E st ud ia n te el nuevo estudiante a agregar * @return true si lo pudo agregar , false si no pq estaba lleno */ public boolean a g r e g a r E s t u d i a n t e ( Estudiante n ue vo E st ud ia n te ) { if ( cantE st u di an te s < estudiantes . length ) { estudiantes [ ca n tE st ud i an te s ++] = n ue vo E st ud ia n te ; return true ; } else { return false ; } } /* * Muestra una lista de los estudiantes */ public void ve rEstudi antes () { String mensaje = " Estudiantes : " ; for ( int i = 0; i < c a nt Es t ud ia nt e s ; i ++) {

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

69

mensaje += " \ n " + ( i + 1) + " ) " + estudiantes [ i ]. getApellido () + " , " + estudiantes [ i ]. getNombre (); } Usuario . mensaje ( mensaje ); } /* * Calcula el promedio de todos los estudiantes de un curso * @param codigoCurso el codigo del curso * @return el promedio simple de los promedios de los estudiantes del curso , * o -1 si no habia nadie en el curso */ public double c a l c u l a r P r o m e d i o C u r s o ( String codigoCurso ) { // Calculamos promedio double suma = 0; int cantEnCurso = 0; for ( int i = 0; i < c a nt Es t ud ia nt e s ; i ++) { if ( estudiantes [ i ]. getCodigo (). equals ( codigoCurso )) { suma += estudiantes [ i ]. c a l c u l ar P r o m e d i o (); cantEnCurso ++; } } // Retornamos promedio if ( cantEnCurso != 0) { return suma / cantEnCurso ; } else { return -1; } } /* * Busca todos los estudiantes cuyo nombre o apellido sean el string * indicado , si importar mayusculas * @param nombre el nombre o apellido del estudiante a buscar * @return un arreglo con los resultados */ public Estudiante [] b u s c a r E s t u d i a n te ( String nombre ) { // Contamos resultados int cantRe sultados = 0; for ( int i = 0; i < c a nt Es t ud ia nt e s ; i ++) { if ( estudiantes [ i ]. getNombre (). toLowerCase () . equals ( nombre . toLowerCase ()) || estudiantes [ i ]. getApellido (). toLowerCase () . equals ( nombre . toLowerCase ())) { cantResultad os ++; } } // Almacenamos arreglo con resultados Estudiante [] resultados = new Estudiante [ cantR esultado s ]; int pos = 0; for ( int i = 0; i < c a nt Es t ud ia nt e s ; i ++) { if ( estudiantes [ i ]. getNombre (). toLowerCase () . equals ( nombre . toLowerCase ()) || estudiantes [ i ]. getApellido (). toLowerCase () . equals ( nombre . toLowerCase ())) { resultados [ pos ++] = estudiantes [ i ]; } } // Retornamos return resultados ; } }

IIC1103 Cap tulo 7: Ordenaci on y B usqueda

70

S-ar putea să vă placă și