Está en la página 1de 70

lica de Chile

Pontificia Universidad Cato


Escuela de Ingeniera
Departamento de Ciencia de la Computacio n

IIC1103 Introduccion a la Programacion

Captulo 7: Ordenaci
on y B
usqueda

Resumen te
orico
La operacion 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 gua telefonica tiene un nombre, una
direccion y un numero de telefono; la gua telefonica esta dispuesta en orden alfabetico de nombres; los
elementos numericos se pueden ordenar en orden creciente o decreciente de acuerdo al valor numerico del
elemento. En terminologa de ordenacion, el elemento por el cual esta ordenado un conjunto de datos (o se
esta buscando) se denomina clave.
Una coleccion de datos (estructura) puede ser almacenada por ejemplo en un array (vector o tabla). Una
estructura se dice que esta ordenada por la clave k si la lista esta en orden ascendente o descendente con
respecto a esta clave. La coleccionde datos se dice que esta en orden ascendente si: i < jimplicaquek[i] <=
k[j]. En cambio, esta en orden descendente si: i > jimplicaquek[i] <= k[j] para todos los elementos de la
coleccion.
Por ejemplo, para una gua telefonica, la lista esta clasificada en orden ascendente por el campo clave k,
donde k[i] es el nombre del abonado (apellidos, nombre). Un ejempo mas simple de n umeros es la coleccion
4514213245 que se encuentra en orden ascendente y la coleccion 757035161412 en cambio se encuentra en
orden descendente.

B
usqueda
Los computadores se emplean frecuentemente para almacenar grandes vol
umenes de datos.
Tener mucha informacion implica tener dificultades para darle real utilidad.

Los algortimos de b
usqueda son fundamentales para poder localizar la informacion relevante en el
menor tiempo posible.
Los algoritmos de ordenacion permiten mantener la informacion ordenada de tal forma que la b
usqueda
se simplifique.

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 Captulo 7: Ordenacion y B


usqueda 1
Declaracion 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
Restriccion

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. Encontro el elemento.

Declaracion 2 public int busquedaBinaria ( String [ ] lista , String buscado ) {


int inicial = 0;
int final = lista.length - 1;
while ( inicial < final ) {
int central = ( inicial + final )/2;
if( buscado.compareTo(lista[central]) > 0){
inicial = central + 1; }
else if( buscado.compareTo(lista [central]) < 0){
final = central - 1; }
else{ return central; }
}
return -1;
}

Ordenaci
on
Dado un arreglo con N elementos, ordenarlo en funcion de alguna caracterstica com
un entre ellos. Por ejem-
plo, 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:

Ordenacion por seleccion.


Ordenacion por burbuja.
Ordenacion por insercion.

IIC1103 Captulo 7: Ordenacion y B


usqueda 2
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
Declaracion 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
Declaracion 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 Captulo 7: Ordenacion y B


usqueda 3
Ordenaci
on por inserci
on
1. Inicialmente se tiene un solo elemento, que obviamente es un conjunto ordenado.

2. Despues, 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. deteniendose cuando se encuentra un elemento menor (todos los elementos mayores han sido desplaza-
dos una posicion a la derecha).
4. En este punto se inserta el elemento k+1 debiendo desplazarse los demas elementos.

Se conoce como Insertion Sort.

Declaracion 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 Captulo 7: Ordenacion y B


usqueda 4
Ejemplos
Problema 1: Patentes
Enunciado
Las antiguas patentes (de automoviles), por ejemplo PL7812, estan compuestas por un string de dos carac-
teres, en el ejemplo PL, y por un n
umero entero de cuatro dgitos, 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 Joaqun. En particular, si la patente PL7812 esta autorizada, entonces tabla[7812] =
PL, y si la patente JK2345 esta autorizada, entonces tabla[2345] = JK. Ademas, si dos o mas
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 estan ambas autorizadas,
entonces tabla[7812] = PLMB; y si las patentes JK2345, RC2345 y DW2345 estan todas autorizadas,
entonces tabla[2345] = JKRCDW.

Escriba el metodo buscar de la clase TablaDePatentes, que busca rapidamente la Patente patente en
el atributo tabla, y devuelve true (verdadero) si patente esta en tabla, y false (falso) en caso contrario.

Criterios de soluci
on
Lo primero que tenemos que hacer es declarar el metodo como nos indican en el enunciado. Luego, con los
metodos 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 Captulo 7: Ordenacion y B


usqueda 5
Problema 2: Distancia entre puntos
Enunciado
Implemente un programa que busque la mayor distancia entre un grupo de puntos e identifique los puntos
que estan 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 mas facil la implementacion cuenta con la clase Punto mostrada a continuacion.

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 ejecucion 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 maxima y la posicion en el arreglo de
los puntos involucrados. Luego dentro del ciclo calculamos la distancia entre los puntos y la comparamos con
la distancia maxima encontrada hasta el momento, actualizando las variables cuando corresponda.

IIC1103 Captulo 7: Ordenacion y B


usqueda 6
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 Captulo 7: Ordenacion y B


usqueda 7
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 ortografa del documento. Para esto, se le pide implementar la clase Diccionario que
pueda construirse con un tama no entero positivo dado, que sera la capacidad maxima del diccionario.
Se le pide implementar los metodos:

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 comparacion usando el metodo compareTo.

Criterios de soluci
on
Para implementar el Diccionario lo mas logico es utilizar un arreglo de String para representar las palabras
que lo componen.
Luego debemos implementar los metodos que nos piden.

Metodo 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 metodo 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.
Metodo AgregarPalabra: Revisamos que el arreglo no este lleno y que la palabra ya no este en el dic-
cionario. Para esto ultimo llamamos al metodo ConsultarPalabra y revisamos si la palabra retornada
por este metodo es igual a la palabra que queremos agregar. Si no es as agregamos el string al arreglo
en la posicion 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 Captulo 7: Ordenacion y B


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

return palabraMenor ;
}
}

IIC1103 Captulo 7: Ordenacion y B


usqueda 9
Problema 4: Analizar c
odigo
Enunciado
Para el siguiente codigo

1. Describa, en castellano, que representa la Clase A

2. Describa, en forma clara y precisa, que hacen los metodos 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 opcion escribir a un lado una tabla con las variables, arreglos y objetos,
e ir anotando los cambios lnea a lnea, realizando una especie de debug manual. Se debe ser bastante

IIC1103 Captulo 7: Ordenacion y B


usqueda 10
sistematico para no equivocarse, y cuidar interpretar correctamente los cambios en las variables, arreglos y
en los objetos. Entendiendo bien cada paso de los metodos se puede interpretar que estan calculando.

Posible soluci
on
1. ClaseA es una lista/conjunto/coleccion 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 Captulo 7: Ordenacion 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 caracter es un char. Debe crear un programa que ordene alfabeticamente esta matriz, pri-
mero las filas y despues, sin cambiar las filas, 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, resuelvalo pensando que este programa de-
be ser aplicable a cualquier matriz de 3x3.

Criterios de soluci
on
Lo importante aqu es darse cuenta de que cada fila de una matriz se puede tratar como un arreglo unidi-
mensional. Para hacer esto ocupamos matriz[i][j] dejando el i estatico. Con esto vamos a ir obteniendo los
valores de nuestras filas. Luego para ordenarlas, se revisa uno por uno los caracteres y se le compara con
todos los otros caracteres de la misma fila. En caso de que sea mayor, se pone a la derecha del caracter
revisado. Luego es cosa de hacer lo mismo pero ahora para las columnas.

IIC1103 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 13
Problema 6: Estadstica de orden
Enunciado
Un numero x es la i-esima estadstica de orden de un vector A si y solo si x es el i-esimo n
umero mas pequeno
del conjunto. As, si A = (1, 2, 4, 1), la primera (1-esima) estadstica de orden es 1, la segunda (2-esima)
estadstica de orden es 1 y la tercera (3-esima) estadstica de orden es 2.

La operacion matricial $ se define entre una matriz M de n m y un vector v de n elementos, y retorna un


vector de n elementos. La siguiente igualdad:

a11 a11 . . . a1m v1 u1
a21 a21 . . . a2m v2 u2

.. .. . . .. $ .. = .. ,
. . . . . .
an1 an2 ... anm vn un
se cumple si y solo si el valor ui es la vi -esima estadstica de orden de (ai1 , ai2 , . . . , aim ).
Por ejemplo, la siguiente igualdad:
1 2 4 3 4
4 5 6 $ 2 = 5 ,
7 8 9 1 7
se cumple porque 4 es la tercera estadstica de orden de (1, 2, 4), 5 es la segunda estadstica de orden de
(4, 5, 6) y 7 es la primera estadstica de orden de (7, 8, 9).

Escriba un metodo 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 tendran dimensiones adecuadas y que los n
umeros en
V no piden estadsticas fuera de rango.

Criterios de soluci
on
Para encontrar la i-esima estadstica de orden de un vector lo que tenemos que hacer es ordenar el arreglo
de menor a mayor. Para esto podemos utilizar cualquier codigo de ordenacion, como por ejemplo selection
sort. Con el arreglo ya ordenado simplemente buscamos en la posicion i-1 y tenemos la i-esima estadstica
de orden.
Luego para implementar el metodo que nos piden tenemos que crear un nuevo arreglo para retornar de tama no
adecuado y luego, con un ciclo, obtener la iesima estadstica de orden de la fila de la matriz correspondiente
seg
un el valor en el arreglo recibido como parametro.

IIC1103 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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].

Ademas, 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 metodo con encabezado:

public int[] encontrarCadenaCreciente(int[] lista)

que recibe como entrada un arreglo de n umeros enteros, y retorna un arreglo conteniendo la cadena cre-
ciente mas 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 mas larga en lista.

Nota: Si existen varias cadenas crecientes en lista que tienen largo maximo, 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 Captulo 7: Ordenacion 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 posicion 2k (0 = k n) un numero de la lista y en 2k + 1
el n
umero de veces que este numero 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 metodo:

public boolean OrdDup(int[] arreglo)

el cual recibe como parametro 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 despues de invocar al metodo 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 contena la lista original, junto con los n
umeros correspondientes de repeticiones.

Notese que OrdDup retorna un valor booleano. Como no todo arreglo representa una lista con repeticio-
nes, OrdDup retorna true si arreglo corresponde a una lista con repeticiones, y false en caso contrario. En
el primer caso, el metodo 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. Notese 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 verificar 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 metodo 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 + 1];
k = k - 1;
}
arreglo [2 * k + 2] = aux ;
arreglo [2 * k + 3] = cant ;
}
return ( true );
}
}

IIC1103 Captulo 7: Ordenacion 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 continuacion.

Los metodos que aparecen a continuacion ya han sido definidos e implementados, no es necesario que conozca
la implementacion, pero s como utilizarlos.

Clase DatosAmigo
Almacena la informacion sobre un amigo: nombre, apellido, celular y email.

Metodos
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 String getApellido(): Retorna el apellido del amigo.
public int getCelular(): Retorna el celular del amigo.
public String getEmail(): Retorna el e-mail del amigo.

Clase Contactos
Almacena la informacion de una lista de contactos.

Atributos

private DatosAmigo[] amigos: Lista de contactos, es un arreglo que almacena los datos de los
amigos.
Metodos
public Contactos(): Constructor de la clase.
public void AgregarAmigo(DatosAmigo da): Permite agregar la informacion de un amigo a la
lista de contactos; automaticamente agranda el arreglo para contener al nuevo amigo.

Se le pide que implemente los siguientes metodos 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 parametro.
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
parametro. Puede suponer que todos los e-mails se escriben en min
usculas.

IIC1103 Captulo 7: Ordenacion y B


usqueda 18
Para ayudarle a entender el funcionamiento deseado, se ilustra a continuacion el funcionamiento de estos
metodos:

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 Captulo 7: Ordenacion y B


usqueda 19
}
}
return nuevo ;
}

IIC1103 Captulo 7: Ordenacion y B


usqueda 20
Problema 10: M
etodo desconocido
Enunciado
Para el siguiente codigo responda las siguientes preguntas:

1. Que muestra el programa en la consola?

2. Que hace metodo1 y como 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 define 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 Captulo 7: Ordenacion 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 permutacion.

IIC1103 Captulo 7: Ordenacion y B


usqueda 22
Problema 11: Tama
no
optimo
Enunciado
En el proceso productivo de una fabrica de envases de lata, se requiere alimentar una maquina cortadora
con la plancha de lata de tama no optimo, de modo de minimizar las perdidas. Una vez definido el tama no
optimo, se ingresa a la maquina el tama no de la plancha de lata (largo y ancho) y el radio de cada crculo,
con lo cual la maquina cortara la mayor cantidad de crculos tal como se muestra en la figura a continuacion.

Considerando que existen N tipos de planchas con medidas distintas (largo y ancho), se solicita crear un
programa que determine cual 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 crculos,
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 crculos y la superficie perdida.

Datos entrada:
N: cantidad de tipos de planchas
Largo y ancho de cada uno de los N tipos de plancha en milmetros.
Radio de corte del crculo requerido en milmetros

Datos salida: Listado de todas las planchas ingresada ordenado de menor a mayor superficie perdida
indicando para cada una:
Largo y Ancho de la plancha
Cantidad de crculos obtenidos.
Superficie perdida en milmetros cuadrados

La cantidad de crculos en la superficie es la siguiente:


Circulos = (Ancho/((2 radio) + 0,5)) (Largo/((2 radio) + 0,5))
Obs. Se debe considerar que la maquina de corte necesita 5 milmetros como mnimo entre cada crculo para
efectuar el corte.

Nota: Los datos de entrada deben ser pedidos al usuario y la informacion de salida debe aparecer en la
consola.

Criterios de soluci
on
Posible soluci
on

IIC1103 Captulo 7: Ordenacion 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 Superf " );
for ( int i = 0; i < n ; i ++) {
for ( int j = 0; j < 4; j ++) {
Usuario . mensaje ( m [ i ][ j ]);
}
}
}

IIC1103 Captulo 7: Ordenacion y B


usqueda 24
Problema 12: B
usqueda Matriz Irregular
Enunciado
Una matriz se dice irregular si algunas de sus filas no tienen el mismo n
umero de columnas. Por ejemplo, la
siguiente es una matriz irregular:

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

En esta pregunta usted debera implementar un metodo con encabezado

public int valor(int[] M, int i, int j)

que recibe como parametros 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 esta en la fila i y columna j de M
(recuerde que la primera fila de una matriz es la numero 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 fila 2 y columna 2 de M es 10.

Importante: El metodo valor debe retornar -1 si el parametro i o el parametro j estan 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. Ademas, su implementacion debe manejar correctamente el caso en que
una fila 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 26
Problema 13: Combate Naval
Enunciado
Usted debera implementar una version simplificada del conocido juego Combate Naval. El juego consta
de un tablero bidimensional sobre el cual se disponen estrategicamente 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 version simplificada, la implementacion que Usted haga resultara en un prototipo que no
es completamente funcional. Sin embargo, su programa debera permitir agregar barcos a su tablero, quitar-
los del mismo, mostrar informacion relevante que de cuenta del estado de una contienda, recibir y procesar
correctamente un ataque, entre otras cosas.

Para la realizacion del laboratorio usted cuenta con la clase Principal, con su respectivo metodo main,
y la clase Oponente, que representa al rival de esta version simplificada del juego, ambas ya implementadas.
Observe que esta clase tiene como u nica finalidad proporcionarle la posibilidad de probar algunos de los
metodos que Usted debera implementar, mediante la generacion 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 Captulo 7: Ordenacion 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 fin de que su desarrollo sea consistente.

Incremento 1
Para completar el primer incremento, debera implementar completamente la clase Barco. A traves de esta
representaremos los barcos que participan del juego. Un barco queda caracterizado por su tipo y su orien-
taci
on dentro del tablero de juego. Ademas, resultara 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 flote o se ya se ha hundido.

A continuacion se detallan los metodos que debera tener esta clase:

1. Barco(int tipo, char orientacion) Constructor de la clase. Recibe la inicializacion de sus ca-
ractersticas esenciales. Un barco se modela como una hilera de segmentos. Luego, su ancho es unitario
y su largo quedara definido por el tipo de barco. El largo mnimo 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 maximo admisible seg un el tipo de
barco. Dado que se trata de una version simplificada del juego, el maximo de ataques certeros que
puede recibir un barco equivale a su largo (su tipo), sin importar si un mismo segmento del barco es
atacado mas de una vez por el rival. De esta manera, para destruir un barco no es necesario que sean

IIC1103 Captulo 7: Ordenacion 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. Metodos para poder obtener estas 4 caractersticas (getters).

Por otro lado, para este incremento debera implementar parcialmente la clase Tablero, que representara la
superficie 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 flota).

Dado que el juego impide que dos barcos esten ocupando un mismo espacio, debera modelar el tablero
de manera tal que almacene informacion acerca de cuales posiciones se encuentran ocupadas y cuales no.
Entonces, debera crear un arreglo bidimensional inicializado con el valor 1 en todas sus celdas para repre-
sentar el vaco inicial del tablero.

Al agregar un barco al tablero, debera poner en las posiciones correspondientes el ndice del barco den-
tro de la flota. Por ejemplo, el primer barco agregado al tablero de juego utilizara el ndice 0 dentro de la
lista, por lo que todas las posiciones que cubra este barco en el tablero de juego, deberan contener el valor
0 en vez del valor 1.

El siguiente ejemplo le permitira entender mejor la situacion. 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 posicion (3,2),
y otro de tipo 5 con orientaci
on V en la posicion (0,6). En tal caso, el arreglo bidimensional quedara 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
La clase Tablero debera tener los siguientes metodos:

1. Tablero(int filas, int columnas, int barcos) Constructor de la clase. Recibe las dimensio-
nes de la superficie de juego, y la cantidad maxima de barcos que pueden ser agregados al tablero. En
la implementacion dada del metodo main observara que este u ltimo n
umero debe cumplir con cierta
restriccion.
2. agregarBarco(Barco barco, int fila, int columna) Permite agregar barco al tablero de juego
a partir de la posicion determinada por (fila, columna). Estas coordenadas corresponden directa-
mente a los ndices del arreglo bidimensional, y seg un la orientacion del barco representan el extremo
superior (V) o izquierdo (H) de este. Verifica, de acuerdo a la cantidad maxima 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 valido y no hay uno igual ya en la flota. Ademas, revisa si las coordenadas son validas, si no so-
brepasara los lmites del tablero segun su orientacion, y si los espacios requeridos para la operacion
estan desocupados. Si no cumple con alguna de estas condiciones, retornara false. En caso contrario,
inserta el barco al final de la lista (o flota) y actualiza las posiciones del arreglo bidimensional con el
numero del ndice que ocupo en la lista, y luego retorna true.
3. void mostrarTablero() Muestra en la consola una visualizacion grafica del estado actual del
tablero, similar a la mostrada mas arriba, pero reemplazando al imprimir los 1 por el caracter .
Luego, para cada barco de la flota, muestra la cantidad de impactos recibidos por ataques del rival y,
si corresponde, si ya fue hundido.

IIC1103 Captulo 7: Ordenacion y B


usqueda 29
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
metodos:

1. boolean hundirBarco(int tipo) Permite quitar un barco del tablero, como tambien de su lista
asociada, solamente seg un el tipo del barco a eliminar dada la caracterstica de que en la flota no puede
haber mas de un barco por cada tipo posible. Si el barco no existe en la flota 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 fin de que no quede un
espacio vaco en la lista ni se desperdicie un ndice. En relacion a esto u
ltimo, no olvide hacer lo propio
con la representacion de la flota 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 flota. Para ello, crea un arreglo
auxiliar con los barcos activos de la flota (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 metodos a la clase Tablero:

1. void poblarTablero() Permite poblar un Tablero de acuerdo a sus parametro de inicializacion.


Ocupando el metodo Aleatorio.entero del paquete del curso y el metodo agregarBarco ya imple-
mentado por Usted, genera la informacion necesaria para crear los barcos que corresponda y agregarlos
exitosamente a la flota.
2. void recibirAtaque(int[] coordenadas) Permite conocer los resultados de un ataque del opo-
nente. Revisa si en el arreglo bidimensional la posicion representada por (coordenadas[0], coordenadas[1])
esta vaca u ocupada por alg un segmento de un barco. Si el ataque fue certero, invoca al metodo
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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 34
Problema 14: Grupos de Novatos
Enunciado
Como bien Ud. sabe, los novatos de Ingeniera son acogidos durante el primer a no por el Cuerpo de Tutores.
En particular, durante el primer semestre, estan en un grupo con otros novatos desarrollando un proyecto
para el curso Desafos de la Ingeniera. 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 debera implementar un programa que permita agrupar a
los novatos seg
un ciertas variables, ademas de permitir realizar operaciones sobre sus datos. El proceso suele
ser mas complicado que el que Ud. implementara.

Para la realizacion del ejercicio usted cuenta con 3 clases ya implementadas que se detallan a continua-
cion.

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 Novato ( int id , String nombre , int puntaje ) { ... }


public int getId () { return id ; }
public void setId ( int id ) { this . id = id ; }
public String getNombre () { return nombre ; }
public void setNombre ( String nombre ) { this . nombre = nombre ; }
public int getPuntaje () { return puntaje ; }
public 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 Captulo 7: Ordenacion 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 fin de que su desarrollo sea consistente.

Incremento 1
Para completar el primer incremento, debera implementar parte de la clase ArmaPaquetesGrupos, la cual
permitira realizar las tareas previamente descritas. Utiliza intensivamente la clase Novato, que ya viene
implementada y cuyos metodos podra apreciar en el respectivo archivo .java; NO LA MODIFIQUE. A
continuacion se detallan los metodos que debera tener ArmaPaquetesGrupos para este primer incremento:
1. public ArmaPaquetesGrupos(int gruposPorPqte, int nroPaquetes) Constructor de la clase.
gruposPorPqte especifica el n umero maximo de grupos que tendra cada paquete, nroPaquetes espe-
cifica el maximo de paquetes en los que se dividira a los novatos.
2. public Novato[] ordenarLista(Novato[] listaNovatos) Ordena la lista de novatos seg
un pun-
taje de forma decreciente1 . Retorna un arreglo unidimensional de tipo Novato.
3. public void armarGrupos(Novato[] listaNovatos) Dado un arreglo de objetos de tipo Novato2 ,
define a que paquete y grupo pertenece cada novato. Para cumplir esta tarea, Ud. debera 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] co-
rresponde al n umero de grupo asignado. Para poder llenar la matriz anterior, debemos determinar
primero a que paquete pertenece cada alumno, y luego asignarle un n umero de grupo valido 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:
1O sea, de mayor a menor puntaje. No se preocupe ante igualdades de puntaje entre 2 o m as alumnos; para esos casos,
resuelva segun 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 implementacion 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

IIC1103 Captulo 7: Ordenacion y B


usqueda 36
indexOrden corresponde al ndice del arreglo listaNovatos[], pasado como parametro.
nroPaquetes el maximo de paquetes, especificado al momento de la construccion de la clase.
El % corresponde al operador de modulo de Java.
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 especifica la cantidad de novatos del paquete correspondiente, a los cuales
ya se les ha asignado grupo4 .
gruposPorPqte corresponde al atributo especificado en el constructor de la clase.
#paquete es el n umero de paquete calculado previamente para el novato en cuestion.
Asuma para este calculo que habra suficientes alumnos para que exista el n
umero de grupos por
paquetes se
nalado al momento de la creacion de la clase.

A continuacion veremos una representacion ficticia de relNovatoGrupo[][], para 10 alumnos, 5 pa-


quetes y 2 grupo de alumnos por paquete5 :

1 0 0 0 0
0 3 0 0 0
0 0 0 0 9
0 0 0 0 10
2 0 0 0 0
0 0 5 0 0
0 0 0 7 0
0 4 0 0 0
0 0 0 8 0
0 0 6 0 0

Las filas representan a los novatos (indexados por su Id), y las columnas representan a los paque-
tes (indexados por su n umero). Por ejemplo, podemos ver que la segunda fila corresponde al alumno
con Id = 1. Si nos desplazamos hacia la derecha por esta misma fila, vemos que todos los n
umeros son
0, salvo uno (en este caso, el 3, que corresponde a su n
umero de grupo). Podemos tambien 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 solo grupo y
a un solo paquete.
4. public void imprimirListaCompleta() Imprime en consola la lista completa de alumnos, orde-
nada decrecientemente por puntaje. Un ejemplo de output para un alumno es el siguiente:
id: 8 nombre: VICENCIO ALBERTO puntaje: 818
Al final de la lista, se debe imprimir el n
umero de alumnos mostrados en consola (por ejemplo: ** Se
encontraron 20 registros)
5. Debe agregar metodos para poder obtener los atributos que debe tener la clase (getters).

Sientase libre de agregar otros metodos seg


un estime necesario para realizar de mejor forma su tarea, pero
debe cumplir como mnimo con los especficados (que deben ce nirse fielmente a las definiciones). Esto es
valido tambien para los otros 2 incrementos.
4 Este valor no incluye al novato sobre el que se est
a calculando su numero de grupo.
5 El resultado es irreal: grupos de un s
olo alumno!. Es s
olo para ilustrar el c
omo sera la matriz requerida.

IIC1103 Captulo 7: Ordenacion y B


usqueda 37
Incremento 2
Para completar el segundo incremento, su programa debe agregar los siguientes metodos 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).

Ademas debera mejorar el metodo imprimirListaCompleta(), para que el output de cada novato incluya
tambien 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 especifiquen su n umero de paquete o grupo, por lo
que debera 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 metodos 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 especificado por menor y mayor(ambos inclusive).
El formato es una lnea por alumno, con los mismos datos que muestra imprimirListacompleta().
Debe mostrar al final de la lista el n
umero de alumnos estan 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 operacion, los dos alumnos deben ser del mismo paquete, pero no
pertenecer al mismo grupo. Este metodo 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 int [][] re lNovato Grupo ;


private Novato [] listaOrdenada ;
private int nroPaquetes ;
private 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 41
Problema 15: Muebles en Habitaci
on
Enunciado
Usted debera implementar un programa que permita posicionar muebles dentro de una habitacion. Su pro-
grama debera permitir agregar muebles a la habitacion para lo cual debera buscar un lugar dentro de la
habitacion donde exista el espacio suficiente para poner el mueble.

Para la realizacion del ejercicio usted cuenta con la clase Principal ya implementada y que se muestra a
continuacion.

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 Captulo 7: Ordenacion 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 fin de que su desarrollo sea consistente.

Incremento 1
Para completar el primer incremento, debera implementar la clase Mueble por completo, la cual representara a
un mueble dentro de su programa. Cada mueble se caracterizara por su nombre, un ancho y un alto. A
continuacion se detallan los metodos que debera tener esta clase.

1. Mueble(String nombre, int ancho, int alto) Constructor de la clase. Recibe la inicializacion
de sus caractersticas.
2. int CalcularArea() Retorna el area del mueble, la cual se calcula multiplicando el ancho por el
alto.

3. Metodos para poder obtener las 3 caractersticas.

Ademas en este incremento debera implementar la clase Habitacion, la cual representara 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 debera 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 indicara que la matriz se encuentra vaca. Cuando agregue un mueble debera 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 utilizara el ndice 0 dentro de la lista, por lo que todas las casillas que este utilice
deberan contener el valor 0 en la matriz.

Por ejemplo, si creo una habitacion 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 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

La clase Habitacion debe tener los siguientes metodos:

1. Habitacion(int ancho, int alto, int maxMuebles) Constructor de la clase. Recibe el ancho y
alto de la habitacion, as como tambien la cantidad maxima de muebles que puede contener.
2. boolean AgregarMueblePosicion(Mueble nuevoMueble, int fila, int col) Permite agregar
un mueble en una posicion determinada. Verifica que la posicion sea valida (se encuentre en los lmites
validos para la habitacion), en caso de no ser valida retorna false. Ademas verifica que sea posible
agregar el mueble en la posicion indicada para lo cual revisa si se encuentran vacos los espacios nece-
sarios seg
un las dimensiones del mueble (la posicion recibida simboliza a la esquina superior izquierda
del mueble). Si es posible agregar el mueble, lo inserta al final de la lista y marca las casillas ocupadas
por este, retornando true.
3. void MostrarHabitacion() Muestra en la consola el estado actual de la habitacion. Primero mues-
tra la matriz segun 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 habitacion, mostrando para cada uno el ndice que le corresponde y
el nombre.

IIC1103 Captulo 7: Ordenacion y B


usqueda 43
Incremento 2
Para completar el segundo incremento, su programa debe agregar los siguientes metodos a la clase Habitacion:

1. boolean AgregarMueble(Mueble nuevoMueble) Permite agregar un nuevo mueble en la primera


posicion que encuentre dentro de la habitacion. 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 metodo 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 metodo a la clase Habitacion:

1. boolean EliminarMueble(String nombre) Permite eliminar un mueble de la habitacion, 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 definir que las casillas que estaba utilizando ahora estan libres. Al removerlo
de la lista debo mover todas los muebles que se encontraban despues 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 despues 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 String getNombre () { return nombre ; }


public int getAncho () { return ancho ; }
public int getAlto () { return alto ; }
public int CalcularArea () { return ancho * alto ; }
}

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;
}
}
}

IIC1103 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 46
Problema 16: Administraci
on Banco
Enunciado
Debe implementar un programa que simule un sistema de administracion de un banco.

Se le pide implementar dos clases: AdminCuentas, y Cuenta. La clase AdminCuentas consistira en un sistema
simple de administracion de cuentas corrientes de un banco; la clase Cuenta, en informacion detallada sobre
una cuenta corriente de una persona.

Ademas, existe una tercera clase, InterfazUsuario, que contiene el main del programa, y que ya esta im-
plementada.

Cuenta: Debe tener los siguientes atributos:


El nombre de la persona asociada a la cuenta corriente en un String.
El apellido de la persona asociada a la cuenta corriente en un String.
El RUT 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 depositos (entrada de dinero).
Un arreglo de enteros para almacenar los giros (salida de dinero).
Ademas, la clase Cuenta debe tener los siguientes metodos:
public Cuenta(String nuevoNombre, String nuevoApellido, String nuevoRUT, String nuevaClave,
int cantMax): El constructor crea un nuevo objeto Cuenta, recibiendo como parametros el nom-
bre, apellido, RUT y clave de la persona, y la cantidad maxima de depositos y giros que tendra (es
decir, puede almacenar hasta cantMax giros, y hasta cantMax depositos). Inicializa con un -1 el
arreglo de depositos y el de giros.
public String getNombre(): retorna el nombre de la persona.
public String getApellido(): retorna el apellido de la persona.
public String getRUT(): retorna el RUT de la persona.
public String getClave(): retorna la clave de la persona.
public boolean agregarDeposito(int monto): recibe un parametro entero que debe agregar
en el arreglo de depositos. 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 parametro 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 depositos (es decir, los que esten en el arreglo
con valor distinto a -1), y retorna la suma.
public int totalGiros(): suma todos los giros (es decir, los que esten 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 depositos y el de
giros).
public int mostrarTodo(): muestra un mensaje en pantalla con informacion de los depositos
y giros. En particular, debe indicar el nombre de la persona asociada a la cuenta, y mostrar una
lista de todos los depositos, seguidos del total de depositos; una lista de todos los giros, seguida
del total de giros; y el saldo total.

IIC1103 Captulo 7: Ordenacion 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.
Ademas, la clase AdminCuentas debe tener los siguientes metodos:
public AdminCuentas(int maxCant): Constructor, recibe como parametro un entero que indica
la cantidad maxima de Cuentas permitida; es decir, cuantos objetos Cuenta puede almacenar
como maximo.
public boolean crearCuenta(Cuenta nuevaCuenta): recibe como parametro un objeto de tipo
Cuenta, y lo agrega al arreglo de cuentas si existe un lugar disponible; si esta 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 posicion en la lista (partiendo de 1); y
su Nombre, Apellido y RUT. Por ejemplo, para el que esta en el lugar 0 mostrara 1) Nombre
Apellido RUT (reemplazando Nombre, Apellido y RUT por los valores para ese caso), en la
siguiente lnea el segundo, luego el tercero, etc.
public Cuenta getCuenta(String RUT, String clave): recibe como parametro 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 con-
tinuacion.

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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 51
return false ;
}
}

/* * Muestra las cuentas existentes */


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

/* * 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 Captulo 7: Ordenacion y B


usqueda 52
Problema 17: Administraci
on Biblioteca
Enunciado
Debe implementar un programa que simule un sistema administracion de una biblioteca.

Se le pide implementar dos clases: SistemaBiblioteca y Libro. La clase SistemaBiblioteca consistira en


un sistema simple de administracion de una biblioteca, y la clase Libro contendra informacion especfica
sobre un libro dado.

Ademas, existira una tercera clase, InterfazUsuario, que contendra el main del programa, y que ya
vendra implementada.

En particular, la clase Libro debe cumplir con lo siguiente:


Debe almacenar el nombre y autor del libro como Strings.
Debe almacenar el codigo 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 posicion indica un da de la semana,
empezando por el da lunes en la posicion 0. El valor almacenado en cada posicion indica la
cantidad de copias del libro reservadas para ese da de la proxima semana (los libros deben ser
reservados de una semana para otra).

Ademas, la clase Libro debe tener los siguientes metodos:


public Libro(String nuevoNombre, String nuevoAutor, String nuevoISBN, int nFecha,
int nCopias): permite crear un nuevo libro, recibiendo como parametros el nombre, autor, ISBN,
ano y cantidad de copias del libro. No es necesario validar el formato del codigo ISBN; cualquier
String sera aceptado como valido. Se asumira que no se crearan dos libros distintos con el mismo
codigo 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 codigo 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 informacion 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 parametro un entero entre 1 y 7 que indica
las reservas de que da se quiere revisar, y retorna las reservas de ese da.
public boolean reservarCopia(int cuando): recibe como parametro un entero entre 1 y 7
indicando para que da de la proxima semana se quiere reservar un libro. Si quedan copias dispo-
nibles (no reservadas), debe aumentar la cantidad de copias reservadas para el da indicado. Por
ejemplo, si el parametro es 1, indica que se quiere reservar una copia para el da 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 Captulo 7: Ordenacion 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 corresponderan a los libros existentes en la
biblioteca.
Debe almacenar la cantidad de libros ya guardados en la lista.

Ademas, la clase SistemaBiblioteca debe tener los siguientes metodos:


public SistemaBiblioteca(int tamanoBiblioteca): recibe como parametro un entero que in-
dica la capacidad de la biblioteca; es decir, cuantos libros puede almacenar como maximo.
public boolean agregarLibro(Libro nuevoLibro): recibe como parametro un objeto de tipo
Libro, y lo agrega a lista de libros de la biblioteca si existe un lugar disponible; si esta llena, no
hace nada. No es necesario que valide si ya existe un libro con el mismo ISBN; se asume que esto
no sucedera. Retorna true si lo pudo agregar, false si no pudo por estar llena.
public Libro[] buscarLibroPorAutor(String autor): recibe como parametro 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 parametro un String con el
codigo 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 parametro un String
con un codigo ISBN, y un n umero entero entre 1 y 7 indicando para que da reservarlo (1 lu-
nes, 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, vendra viene ya implementada y se muestra
a continuacion.

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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 57
}
}

IIC1103 Captulo 7: Ordenacion y B


usqueda 58
Problema 18: Administraci
on Regalos Novios
Enunciado
Debe implementar un programa que simule un sistema de administracion de una lista de regalos de novios.

Se le pide implementar dos clases: AdminNovios y Novios. La clase AdminNovios consistira en un siste-
ma simple de administracion de listas de regalos de novios; la clase Novios, en informacion sobre una pareja
de novios.

Ademas, existiran dos clases mas que vendran implementadas: InterfazUsuario, que contendra el main
del programa, y Regalo, que contendra informacion especfica 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).
Ademas, la clase Novios debe tener los siguientes metodos:
public Novios(String nuevoNovio, String nuevaNovia, int cantMaxima): permite crear un
nuevo elemento Novios, recibiendo como parametros el nombre del novio, el nombre de la novia,
y la cantidad maxima de regalos que podran 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 parametro un objeto de
tipo Regalo. Revisa si ya esta en la lista de no comprados; si no esta, lo agrega a la lista; si esta,
no hace nada y retorna falso. Retorna true si lo pudo agregar, false si no pudo por no haber mas
espacio.
public void mostrarRegalosNoComprados(String categoria): recibe como parametro un String
indicando una categora, y muestra en pantalla un mensaje indicando toda la informacion de los
regalos no comprados correspondientes a esa categora (nombre, categora). Si la categora es un
String vaco (), muestra todos los regalos no comprados.
public void mostrarRegalosYaComprados(String categoria): recibe como parametro un String
indicando una categora, y muestra en pantalla un mensaje indicando toda la informacion de los
regalos ya comprados correspondientes a esa categora (nombre, categora). Si la categora es un
String vaco (), muestra todos los regalos ya comprados.
public boolean comprarRegalo(String nombreRegalo): recibe como parametro un String con
el nombre de un Regalo. Revisa si existe ese regalo en la lista de no comprados; si no esta, retorna
false. Si esta, 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 metodo mas o menos generico para buscar la posicion de algo en un
arreglo, como metodo privado en la clase Novios, para facilitarle el desarrollo de los otros metodos y re-
escribir menos codigo.

Por otro lado, la clase AdminNovios debe cumplir con lo siguiente:

IIC1103 Captulo 7: Ordenacion y B


usqueda 59
Debe almacenar un arreglo de Novios.
Debe almacenar la cantidad de objetos Novios almacenados en el arreglo.
Ademas, la clase AdminNovios debe tener los siguientes metodos:
public AdminNovios(int cantMaxima): recibe como parametro un entero que indica la cantidad
maxima de Novios permitida; es decir, cuantos objetos Novios puede almacenar como maximo.
public boolean agregarNovio(Novios nuevoNovio): recibe como parametro un objeto de tipo
Novio, y lo agrega a lista de novios si existe un lugar disponible; si esta lleno, no hace nada. Retorna
true si lo pudo agregar, false si no pudo por estar lleno.
public Novios[] buscarNovios(String nombre): recibe como parametro un String con el nom-
bre de un novio o novia, y busca todos los novios con esa informacion en el arreglo. Retorna un
arreglo con los Novios encontrados.

La clase Regalo y la clase InterfazUsuario vienen ya implementadas y se describen a continuacion.

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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 de regalos
private Regalo [] noComprados ;
private Regalo [] yaComprados ;
private int ca n tN oC o mp ra do s = 0;
private 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 64
Problema 19: Administraci
on Notas
Enunciado
Debe implementar un programa que simule un sistema de administracion de notas.

Se le pide implementar dos clases: AdminEstudiantes, y Estudiante. La clase AdminEstudiantes consis-


tira en un sistema simple de administracion de informacion de estudiantes; la clase Estudiante, consistira en
informacion detallada sobre un estudiante en particular y sus notas.

Ademas, existira una tercera clase, InterfazUsuario, que contendra el main del programa, y que vendra im-
plementada.

Estudiante: Debe tener los siguientes atributos:


El nombre del estudiante en un String.
El apellido del estudiante en un String.
Un codigo del curso en que esta 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 esta.
Un arreglo de enteros con la ponderacion de cada una de las notas almacenadas en el arreglo
anterior.
Ademas, la clase Estudiante debe tener los siguientes metodos:
public Estudiante(String nuevoNombre, String nuevoApellido, String nuevoCodigo, int
cantNotas): El constructor crea un nuevo objeto Estudiante, recibiendo como parametros el nom-
bre del estudiante, el apellido del estudiante, el codigo del curso y la cantidad maxima de notas
que tendra. Inicializa con un 0 en todas las notas, y en 0 todas las ponderaciones y fija 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 codigo del curso del estudiante.
public void setNota(int numNota, double nota): recibe como parametro un entero entre 1
y la cantidad maxima de notas (es decir indica si es la primera, segunda, tercera nota, etc. hasta
la cantidad maxima de notas). El otro parametro 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 parametro recibido esta en el rango correcto.
public void setPonderacion(int numPonderacion, int ponderacion): recibe como parame-
tro un entero entre 1 y la cantidad maxima de notas (indicando si es la ponderacion de la primera,
segunda, tercera, etc. ponderacion), y un entero con el porcentaje de ponderacion de la nota. La
ponderacion se almacena en el arreglo (recordar que en los arreglos, los lugares parten de 0). Debe
validar si el parametro recibido esta 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 pon-
deracion; tambien muestra el promedio y la mejor nota.

AdminEstudiantes: Debe tener los siguientes atributos:

IIC1103 Captulo 7: Ordenacion 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.
Ademas, la clase AdminEstudiantes debe tener los siguientes metodos:

public AdminEstudiantes(int maxEstudiantes): Constructor, recibe como parametro un en-


tero que indica la cantidad maxima de Estudiantes permitida; es decir, cuantos objetos Estudiante
puede almacenar como maximo.
public boolean agregarEstudiante(Estudiante nuevoEstudiante): recibe como parametro
un objeto de tipo Estudiante, y lo agrega al arreglo de estudiantes si existe un lugar disponible; si
esta 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 posicion en la lista (partiendo
de 1); y su Apellido, Nombre separados por ,. Por ejemplo, para el que esta en el lugar 0
mostrara 1) Apellido, Nombre, en la siguiente lnea el segundo, luego el tercero, etc.
public double calcularPromedioCurso(String codigoCurso): recibe como parametro un String
con el codigo 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
ningun estudiante de ese curso, debera retornar -1.
public Estudiante[] buscarEstudiante(String nombre): recibe como parametro un String,
que puede contener el nombre o el apellido, y lo busca en la lista. Debe ser no sensible a las
mayusculas; es decir, debe encontrar al estudiante sin importar si el String buscado (nombre o
apellido) tienen mayusculas o minusculas. 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 esta implementada y se detalla a conti-
nuacion.

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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion 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 Captulo 7: Ordenacion y B


usqueda 70

También podría gustarte