Sunteți pe pagina 1din 63

Pontificia Universidad Catolica de Chile Escuela de Ingenier a Departamento de Ciencia de la Computacion IIC1103 Introduccin a la Programacin o o

Cap tulo 6: Arreglos Resumen terico o


Arreglos
Hasta ahora poco a poco hemos podido almacenar y trabajar con informacin en java de manera cada vez o ms eciente. a Sin embargo, cuando tenemos que trabajar con muchos objetos del mismo tipo, el cdigo se vuelve un poco o ineciente. Por eso es que existen estructuras llamadas arreglos, que hacen las veces de vectores, donde se puede almacenar informacin del mismo tipo. o Es como una caja seccionada, donde podemos guardar un dato en cada casilla. Supongamos que cada casilla guarda la palabra que representa a un nmero. u

Algo importante es que al denir un arreglo, ste asigna posiciones a cada uno de los datos almacenados e comenzando desde CERO, entonces si el arreglo llega hasta la posicin n, tendr n+1 elementos. o a Por ejemplo: Arreglo de Strings Podemos denirlo asignando el nmero de posiciones que tendr al instante. u a //declaracion del arreglo String[] nombres=new String[3]; nombres[0]="Juan"; nombres[1]="Pablo"; nombres[2]="Ana"; Podemos denirlo tambin de un largo determinado en un ciclo o directamente con sus elementos. e //declaracion del arreglo directamente char[] iniciales={a,b,c}; Es com n asignar valores a los arreglos recorriendo cada una de sus casillas. u //declaracion en un ciclo con los mltiplos de 17 u int[] multiplos=new int[10]; for (int i=0; i<10; i++) { multiplos[i]=(i+1)*17; }

IIC1103 Cap tulo 6: Arreglos

Para utilizar la informacin que guarda el arreglo en una determinada posicin, lo llamamos de la siguiente o o manera: <identificador>[i] Por ejemplo en el caso de los m ltiplos, si yo quisiera averiguar el 5 deg mltiplo de 17, tengo que escribir: u u int quinto=multiplos[4]; Entonces quinto = 5x17 (ojo con las posiciones que estn denidas para el arreglo, comienzan desde cero). a Podemos tener arreglos de cualquier cosa, de String, int, char, objetos, arreglos, etc. Importante: Para denir un arreglo se debe utilizar el smbolo [ ]. De la siguiente manera inicializamos el arreglo: <tipo>[ ] <identificador> = new <tipo>[n] ; Aunque cada una de las posiciones por defecto est vac o nula (null). a a Al igual que los otros objetos podemos crearlo y no inicializarlo hasta que sea necesario, lo importante es que ANTES de asignarle valores a cada espacio, debemos indicarle al arreglo su largo (a menos que lo creemos directamente, lo que no es muy usual). Existen algunos comandos que se utilizan con los arreglos, por ejemplo, para saber el largo del arreglo, tenemos: <identificador>.length; Que nos devolver el ndeg de valores que almacena el arreglo, es decir, al nmero que ingresamos al declaa u rarlo. Por ejemplo, si nuestro arreglo tiene casillas 0, 1 y 2, lenght nos retornar 3. a Un arreglo NO se puede asignar a otro arreglo, por ejemplo, si se tiene que: int[] Pares={2, 4, 6, 8, 10}; int[] num=new int[5]; No puedo hacer la asignacin siguiente: o num=Pares; Esta asignacin no copiar los valores, si no que, al igual que en los objetos, cambiar la referencia num, o a a de manera que apunte a la misma direccin de memoria que Pares. Para todos los efectos, ambas variables o Pares y num estarn apuntando al mismo arreglo. Para copiar los valores la forma correcta es: a for (int i=0; i<num.length; i++) { num[i]=Pares[i]; }

IIC1103 Cap tulo 6: Arreglos

Matrices
Las matrices no son ms que arreglos de arreglos, simplemente como un dato guardado en un espacio que a ahora no se dene por una posicin, sino por un par de coordenadas. o

Las matrices pueden ser regulares o irregulares, es decir, puede que en cada la, el nmero de elementos sea u distinto, o pueden no ser cuadradas, etc. La forma de denirlas es: <tipo>[ ][ ] <identificador> = new <tipo>[ ][ ];

IIC1103 Cap tulo 6: Arreglos

Ejemplos
Problema 1: Preguntas Varias
Enunciado Responda las siguientes preguntas: 1. Responda las siguientes preguntas en base al arreglo: int[] array = {0,1,2,3}: a) Si se realiza la instruccin array[1] = array[2]; seguida por la instruccin array[2] = array[2] o o + 1;, cules son los valores del arreglo array?por qu? a e b) Si se realiza la instruccin array[1] = array[2]; seguida por la instruccin array[2] = 4;, o o cules son los valores del arreglo array?por qu? a e
String [] array = { " las " ," los " , " el " ," un " };

2. Responda las siguientes preguntas en base al arreglo: a) Si se realiza la instruccin array[1] = array[2]; seguida por la instruccin array[2] = array[2] o o + "la";, cules son los valores del arreglo array?por qu? a e b) Si se realiza la instruccin array[1] = array[2]; seguida por la instruccin array[2] = "la";, o o cules son los valores del arreglo array?por qu? a e 3. Existe la clase Auto declarada de la siguiente forma:
class Auto { private String color ; private int agno ; public Auto ( String _color , int _agno ) {...} public String getColor () { return color ; } public int getAgno () { return agno ; } public void setColor ( String nuevo ) { color = nuevo ; } public void setAgno ( int nuevo ) { agno = nuevo ; } }

Responda las siguientes preguntas en base al arreglo:


Auto [] array = { new Auto ( " gris " , 2000) , new Auto ( " azul " , 1999) , new Auto ( " blanco " , 2005) , new Auto ( " rojo " , 2000)}:

a) Si se realiza la instruccin array[1] = array[2]; seguida por la instruccin o o array[2].setAgno(array[2].getAgno()+1);, cules son los valores de los atributos de los oba jetos del arreglo array?por qu? e b) Si se realiza la instruccin array[1] = array[2]; seguida por la instruccin array[2] = new o o Auto("negro", 2009);, cules son los valores de los atributos de los objetos del arreglo array?por a qu? e c) Si se realiza la instruccin array[3].setColor("gris") cul es el resultado de la comparacin o a o array[0] == array[3]?por qu? e Criterios de solucin o En este ejercicio lo importante es tener claro cuando las variables se copian por valor y cuando por referencia. En las dos primeras preguntas, al tratarse de arreglos de enteros y Strings las variables se copian por valor, por lo que luego de copiadas quedan completamente independientes. Cuando se trata de objetos las variables se copian por referencia, lo que implica que ambas (la original y la nueva copiada) referencian al mismo objeto y los cambios que se hagan a una se reejan tambin en la otra. e IIC1103 Cap tulo 6: Arreglos 4

Posible solucin o 1. Solucin o a) 0,2,3,3 La primera instruccin hace una copia desde la posicin 1 a la 2, y la segunda instruccin soo o o lamente modica el valor en el casillero 2, ya que por ser int los casilleros 1 y 2 se mantienen independientes. b) 0,2,4,3 La misma justicacin anterior, como la primera instruccin realiza una copia del valor de la o o casilla 2 a la 1, ambas se mantienen independientes. 2. Solucin o a) { " las " ," el " ," ella " ," un " }; La primera instruccin hace una copia de la referencia de la casilla 2 a la casilla 1, mostrando o ambos el mismo valor. La segunda instruccin modica el String en la casilla 2, creando un nuevo o String (son inmutables) independiente del String en la casilla 1. b) { " las " ," el " ," la " ," un " }; Al igual que la pregunta anterior, la primera instruccin hace una copia de la referencia de la o casilla 2 a la casilla 1, mostrando ambos el mismo valor. La segunda instruccin crea un nuevo o String en la casilla 2, independiente del String en la casilla 1. 3. Solucin o a) { Auto ( " gris " , 2000) , Auto ( " blanco " , 2006) ,
Auto ( " blanco " , 2006) , Auto ( " rojo " , 2000)}:

Con la primera instruccin, tanto la casilla 1 como la 2 del arreglo referencian al mismo objeto. o Al modicar este objeto con la segunda instruccin, cambian los atributos del objeto referenciado o tanto por la casilla 1 como por la 2, dado que son el mismo. b) { Auto ( " gris " , 2000) , Auto ( " blanco " , 2005) ,
Auto ( " negro " , 2009) , Auto ( " rojo " , 2000)}:

Con la primera instruccin, tanto la casilla 1 como la 2 del arreglo referencian al mismo objeto. o Pero la segunda instruccin crea un nuevo objeto en la casilla 2, lo que hace que esta quede o independiente del objeto referenciado por la casilla 1. Por ende, la segunda instruccin no afecta o a la casilla 1. c) La comparacin es a nivel de objetos, no de los valores de los atributos. Por ende, la comparacin o o es false, ya que los objetos referenciados por la casilla 0 y por la casilla 3 son distintos (aunque el valor de los atributos sea el mismo).

IIC1103 Cap tulo 6: Arreglos

Problema 2: Ms Repetidos a
Enunciado En esta pregunta usted debe implementar un mtodo con encabezado: e
public int repetidos ( int arreglo [])

que recibe como entrada un arreglo de nmeros enteros mayores o iguales que cero, y retorna el valor en el u arreglo que aparece repetido un mayor nmero de veces. Por ejemplo, si arreglo almacena la lista de n meu u ros [1, 33, 4, 2, 4, 97, 0, 5, 4, 3, 48, 6, 4, 4, 3], entonces repetidos retorna el valor 4, ya que ste es el n mero e u que aparece repetido una mayor cantidad de veces en arreglo. Nota: Si hay dos o ms n meros que satisfagan la condicin mencionada arriba, entonces el mtodo a u o e repetidos tiene que retornar alguno de ellos. Criterios de solucin o Una manera de resolver este ejercicio es utilizar un arreglo auxiliar que en la posicin i almacene el n mero o u de veces que el n mero i aparece en el arreglo original. Para hacer esto lo primero que debemos obtener u es el valor mximo que contiene el arreglo original pues este valor representar el largo de nuestro arreglo a a auxiliar. Luego llenamos el arreglo auxiliar aumentando en uno la cuenta en la posicin adecuada segn el o u n mero que aparezca en el arreglo original. Finalmente, revisamos el arreglo auxiliar y obtenemos el mayor u valor guardado, donde la posicin nos dar el n mero al que corresponde el mayor nmero de repeticiones. o a u u Posible solucin o
public int r e p e t i d o s( int arreglo []) { int i , max , indice ; int aux []; max = 0; for ( i = 1; i < arreglo . length ; i ++) { if ( arreglo [ i ] > max ) { max = arreglo [ i ]; } } aux = new int [ max + 1]; for ( i = 0; i < max + 1; i ++) { aux [ i ] = 0; } for ( i = 0; i < arreglo . length ; i ++) { aux [ arreglo [ i ]]++; } max = aux [0]; indice = 0; for ( i = 1; i < aux . length ; i ++) { if ( aux [ i ] > max ) { max = aux [ i ]; indice = i ; } } return ( indice ); }

IIC1103 Cap tulo 6: Arreglos

Problema 3: Patrones
Enunciado Se le ha pedido ayuda para escribir un programa que detecte patrones anmalos en el funcionamiento de o maquinaria industrial en una fbrica. a Cada d una mquina registra minuto a minuto su temperatura de funcionamiento, la cual es almacenada a a en un arreglo como el que se muestra a continuacin: o

Se han establecido dos condiciones que revelan un posible funcionamiento anmalo en una mquina: o a Oscilacin: la cual se reconoce cuando aumenta (o disminuye) la temperatura en dos intervalos consecuo tivos (t1 > t0 y t2 > t1) y luego disminuye (o aumenta) la temperatura en dos intervalos consecutivos (t3 < t2 y t4 < t3). En el arreglo anterior, se pueden apreciar los dos tipos de oscilaciones: una ascendente (a partir del instante 4) y otra descendente (a partir del instante 11). Ciclicidad diaria: la cual se produce cuando en dos d seguidos se repite una secuencia de tres tempeas raturas en el mismo instante del d Si el siguiente arreglo corresponde al d siguiente al del arreglo a. a anterior: Entonces hay ciclicidad diaria a partir del instante 2, del instante 9 y del instante 16. Escriba en lenguaje Java los siguientes mtodos para ayudar a detectar comportamientos anmalos: e o a) DetectarOscilaciones // Muestra en consola mensajes indicando oscilaciones // Recibe un arreglo que contiene las temperaturas registradas en un da // cualquiera public static void DetectaOscilaciones(int[] regDia1) { ... } En el caso anterior, deber desplegar los siguientes mensajes: a Oscilacin ascendente a partir del instante 4 o Oscilacin descendente a partir del instante 11 o b) DetectarCiclicidad // Muestra en consola mensajes indicando ciclicidades // Recibe dos arreglos que contienen las temperaturas de dos das // consecutivos public static void DetectaCiclicidad(int[] regDia1, int[] regDia2) { ... } En el caso anterior, deber desplegar los siguientes mensajes: a Ciclicidad diaria a partir del instante 2 Ciclicidad diaria a partir del instante 9 Ciclicidad diaria a partir del instante 16

IIC1103 Cap tulo 6: Arreglos

Criterios de solucin o NOTA: el ndice de la ultima posicin de un arreglo es, ocupando como ejemplo regDia1, regDia1.length-1, o ya que los ndices parten desde cero. a) En este problema lo importante es darse cuenta de que slo hay que comparar enteros y la verdadera o dicultad se encuentra en sacar estos enteros de los arreglos. Por esto, para comparar el da t con el d t+1, a sacamos el entero t+1 del arreglo (regDia1[t+1]) y lo comparamos con el entero t del arreglo (regDia1[t]). Esto luego se hace para t+2, t+3 y t+4 buscando la condicin indicada por el enunciado. Es importante o notar que el for llega hasta la ante ante ante penltima posicin del arreglo (regDia1.length-4) ya que, o si u o no, al pedir el entero regDia1[t+4] este estar fuera del arreglo. a b) Esto es muy similar al ejercicio anterior, la diferencia est en que, en vez de comparar enteros dentro de a un mismo arreglo, se comparan entre dos arreglos distintos.

Posible solucin o
// Parte a ) // Muestra en consola mensajes i n d i c a n d o o s c i l a c i o n e s // Recibe un arreglo que almacena la t e m p e r a t u r a en un dia c u a l q u i e r a public static void D e t e c t a O s c i l a c i o n e s( int [] regDia1 ){ int t ; for ( t =0; t < regDia1 . length -4; t ++) // llegamos solo hasta la a n t e p e n u l t i m a posicion { if ( regDia1 [ t +1] > regDia1 [ t ] && // si se cumple la c o n d i c i o n para a s c e n d e n t e regDia1 [ t +2] > regDia1 [ t +1] && regDia1 [ t +3] < regDia1 [ t +2] && regDia1 [ t +4] < regDia1 [ t +3]){ Usuario . m e n s a j e C o n s o l a( " O s c i l a c i o n a s c e n d e n t e a partir del instante " + t ); } else if ( regDia1 [ t +1] < regDia1 [ t ] && // si se cumple la c o n d i c i o n para d e s c e n d e n t e regDia1 [ t +2] < regDia1 [ t +1] && regDia1 [ t +3] > regDia1 [ t +2] && regDia1 [ t +4] > regDia1 [ t +3]){ Usuario . m e n s a j e C o n s o l a( " O s c i l a c i o n d e s c e n d e n t e a partir del instante " + t ); } } } // Parte b ) // Muestra en consola mensajes i n d i c a n d o c i c l i c i d a d e s // Recibe dos arreglos que a l m a c e n a n la t e m p e r a t u r a en dos dias // c o n s e c u t i v o s public static void D e t e c t a C i c l i c i d a d( int [] regDia1 , int [] regDia2 ) { int t ; for ( t =0; t < regDia1 . length -2; t ++) { if ( regDia1 [ t ] == regDia2 [ t ] && regDia1 [ t +1] == regDia2 [ t +1] && regDia1 [ t +2] == regDia2 [ t +2]) { Usuario . m e n s a j e C o n s o l a( " C i c l i c i d a d diaria a partir del instante " + t ); } } }

IIC1103 Cap tulo 6: Arreglos

Problema 4: Lista Nmeros u


Enunciado Escriba la clase ListaNumeros que reciba un arreglo de enteros. Esta clase debe proveer los mtodos e ElementoMayor() que retorna el mayor elemento dentro del arreglo, ElementoMenor(), que retorna el menor elemento dentro de la lista y ElementoMasRepetido() que retorna el valor del elemento que ms veces a aparece en el arreglo. Criterios de solucin o Para el mtodo ElementoMayor lo que tenemos que hacer es tener una variable donde almacenar el mayor e valor. Luego recorremos todo el arreglo y comparamos cada elemento con el mayor valor, si el elemento es mayor entonces actualizamos el mayor valor. Al terminar el ciclo que recorre todo el arreglo, en la variable estar el mayor valor del arreglo. a Para el mtodo ElementoMenor hacemos lo mismo que para el mtodo anterior pero comparamos si el e e elemento del arreglo es menor que el valor guardado en nuestra variable que almacena el menor valor en este caso. Para el mtodo ElementoMasRepetido ocupamos dos variables, una que guarde el nmero que se ha repetido e u ms veces y otra para guardar cuantas veces se ha repetido. Con un ciclo recorremos todo el arreglo, para a cada elemento contamos (utilizando otro ciclo que recorra todo el arreglo) cuantas veces aparece. Luego comparamos este nmero de veces con el n mero que hasta el momento tenga mayor nmero de repeticiones u u u y actualizamos su valor si es necesario. Posible solucin o
public class L i s t a N u m e r o s { private int [] a r r e g l o E n t e r o s; public L i s t a N u m e r o s( int [] lista ) { // Copiamos el arreglo a r r e g l o E n t e r o s = new int [ lista . length ]; for ( int i = 0; i < a r r e g l o E n t e r o s. length ; i ++) { a r r e g l o E n t e r o s[ i ] = lista [ i ]; } } public int E l e m e n t o M a y o r() { int mayor = a r r e g l o E n t e r o s[0]; for ( int i = 1; i < a r r e g l o E n t e r o s. length ; i ++) { if ( a r r e g l o E n t e r o s[ i ] > mayor ) { mayor = a r r e g l o E n t e r o s[ i ]; } } return mayor ; } public int E l e m e n t o M e n o r() { int menor = a r r e g l o E n t e r o s[0]; for ( int i = 1; i < a r r e g l o E n t e r o s. length ; i ++) { if ( a r r e g l o E n t e r o s[ i ] < menor ) { menor = a r r e g l o E n t e r o s[ i ]; } } return menor ; } public int E l e m e n t o M a s R e p e t i d o() { // Buscamos cuantas veces aparece cada elemento , y g u a r d a m o s el que mas // aparezca int m a s R e p e t i d o = 0; int masVeces = 0; for ( int i = 0; i < a r r e g l o E n t e r o s. length ; i ++) { // Reviso cuantas a p a r i c i o n e s tiene el elemento i int contador = 0; for ( int j = 0; j < a r r e g l o E n t e r o s. length ; j ++) {

IIC1103 Cap tulo 6: Arreglos

if ( a r r e g l o E n t e r o s[ i ] == a r r e g l o E n t e r o s[ j ]) { contador ++; } } // Veo si el elemento i tiene mas a p a r i c i o n e s que el con mas // a p a r i c i o n e s hasta el momento if ( contador > masVeces ) { masVeces = contador ; m a s R e p e t i d o = a r r e g l o E n t e r o s[ i ]; } } return m a s R e p e t i d o; } }

IIC1103 Cap tulo 6: Arreglos

10

Problema 5: Calcular Primos


Enunciado Escriba un programa en JAVA que calcule los nmeros primos del 1 al 100 utilizando la criba de Eratosteu nes. Este algoritmo consiste en crear una lista con los n meros del 1 al 100 y luego ir descartando primero los u m ltiplos de 2, luego los de 3, los de 4 y as sucesivamente hasta los m ltiplos de 10. u u Criterios de solucin o Siguiendo la descripcin del algoritmo implementamos un ciclo que parta de 2 hasta 10 (para ir descartando o los m ltiplos de estos nmeros). Dentro de este ciclo implementamos otro que recorra todo el arreglo original u u y revise para cada elemento si es mltiplo. Si lo es debemos sacarlo del arreglo, para lo que corremos todos u los elementos hacia la izquierda a partir del elemento que queremos borrar. Finalmente imprimimos el arreglo con los nmeros que nos quedan, siempre cuidando que al haber menos u elementos no podemos recorrer todo el arreglo sino slo hasta donde tenemos almacenados nmeros. o u Posible solucin o
import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { int [] numeros = new int [100]; for ( int i = 0; i < numeros . length ; i ++) numeros [ i ] = i + 1; // Al comienzo decimos que todos son primos int n u m P r i m o s = 100; for ( int i = 2; i <= 10; i ++) { for ( int j = 0; j < n u m P r i m o s; j ++) { // R e v i s a m o s si el elemento j es multiplo del valor i // En caso de que sea debemos sacarlo del arreglo if ( numeros [ j ] % i == 0) { // Debemos sacar el elemento j , para eso corremos todos los // e l e m e n t o s hacia la i z q u i e r d a a partir del elemento j for ( int k = j ; k < n u m P r i m o s - 1; k ++) { numeros [ k ] = numeros [ k + 1]; } // Tenemos un numero primo menos numPrimos - -; // Como corri todo hacia la i z q u i e r d a debo volver a reviser // en la posicion j j - -; } } } // M o s t r a m o s los numeros e n c o n t r a d o s for ( int i = 0; i < n u m P r i m o s; i ++) { Usuario . m e n s a j e C o n s o l a( numeros [ i ] + " es primo . " ); } } }

IIC1103 Cap tulo 6: Arreglos

11

Problema 6: Cdigo Desconocido o


Enunciado Indique lo que el siguiente cdigo muestra en la consola o
import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { int [] arreglo = { 171 , 472 , 96 , 443 , 112 , 78 , 352 , 320 , 70 }; Metodo ( arreglo ); } public static void Metodo ( int [] arreglo ) { int x = arreglo [0]; for ( int i = 1; i < arreglo . length ; i ++) { if ( arreglo [ i ] > x ) { x = arreglo [ i ]; } } for ( int n = 10; 10 * x / n > 0; n = n * 10) { int [] temp = new int [10]; for ( int i = 0; i < temp . length ; i ++) { temp [ i ] = 0; } for ( int i = 0; i < arreglo . length ; i ++) { temp [( arreglo [ i ] % n ) / (( int ) ( n / 10))]++; } for ( int i = 1; i < temp . length ; i ++) { temp [ i ] += temp [ i - 1]; } Imprimir ( temp ); int [] aux = new int [ arreglo . length ]; for ( int i = arreglo . length - 1; i >= 0; i - -) { aux [ temp [( arreglo [ i ] % n ) / (( int ) ( n / 10))] - 1] = arreglo [ i ]; temp [( arreglo [ i ] % n ) / (( int ) ( n / 10))] - -; } for ( int i = 0; i < arreglo . length ; i ++) { arreglo [ i ] = aux [ i ]; } Imprimir ( arreglo ); } } public static void Imprimir ( int [] arreglo ) { String texto = " " ; for ( int i = 0; i < arreglo . length ; i ++) { texto += arreglo [ i ] + " " ; } Usuario . m e n s a j e C o n s o l a( texto ); } }

Criterios de solucin o En ste tipo de problemas es buena opcin escribir a un lado una tabla con las variables, arreglos y objetos, e o e ir anotando los cambios l nea a l nea, realizando una especie de debug manual. Se debe ser bastante sistemtico para no equivocarse, y cuidar interpretar correctamente los cambios en las variables, arreglos y a en los objetos. Posible solucin o 2 3 6 7 7 7 8 8 9 9 320 70 171 472 112 352 443 96 78 0 1 2 2 3 4 4 8 8 9 112 320 443 352 70 171 472 78 96 3 5 5 7 9 9 9 9 9 9 70 78 96 112 171 320 352 443 472

IIC1103 Cap tulo 6: Arreglos

12

Problema 7: Histograma
Enunciado Un histograma es una representacin grca (o como tabla) de las frecuencias de ciertos datos, distribuidos o a en alguna cantidad de categor Por ejemplo en los siguientes datos: as. 0, 2, 4, 5, 3, 12, 1, 4, 5, 121, 78, 12, 56, 1, 7, 9, 12, 13, 25, 24, 28, 6, 65, 91, 14, 75, 10 . . . podr amos denir las categor x 20, 20 < x 50 y 50 < x, con lo que se produce el siguiente as histograma: X x 20 20 < x 50 50 < x Frecuencia 18 3 6

Se le pide implementar la clase Histograma que permita crear un histograma de una serie de n meros u enteros comprendidos en un rango establecido al momento de inicializar el objeto, y usando como categoras los mismos n meros, es decir, contar cuantas veces se repite cada nmero en el rango. Use un mtodo Agregar u u e que permita agregar un nuevo valor al Histograma. Criterios de solucin o Para denir nuestra clase Histograma utilizamos como atributos un arreglo que lleve el conteo de las apariciones de los n meros y variables que nos permitan identicar el rango en el que se encuentran los n meros. u u As nuestro arreglo debe ser del tamao suciente para almacenar el conteo de todos los valores posibles n dentro del rango denido. Luego creamos un mtodo Agregar como nos dice el enunciado que lo que hace es revisar en que posicin e o del arreglo se est acumulando el valor recibido como parmetro (la cual ser el valor ingresado menos el a a a l mite inferior del rango) y aumentamos la cantidad almacenada en esa posicin en uno. o Para completar nuestra clase agregamos un mtodo Mostrar que recorre el arreglo donde almacenamos el e conteo y muestra cada valor (correspondiente a la posicin en el arreglo ms el l o a mite inferior) y la cantidad almacenada en l. e

IIC1103 Cap tulo 6: Arreglos

13

Posible solucin o
import i i c 1 1 0 3 P a c k a g e .*; public class H i s t o g r a m a { private int [] conteo ; private int limInf ; private int limSup ; private int cantidad ; // Constructor , recibe los limites de los valores public H i s t o g r a m a( int limInf , int limSup ) { this . limInf = limInf ; this . limSup = limSup ; this . cantidad = limSup - limInf + 1; conteo = new int [ cantidad ]; for ( int i = 0; i < conteo . length ; i ++) { conteo [ i ] = 0; } } // Agrega un valor al Histograma , para ello busca en que posicion del arreglo // se esta a c u m u l a n d o ese valor public void Agregar ( int valor ) { conteo [ valor - limInf ] = conteo [ valor - limInf ] + 1; } public void Mostrar () { int limite = limSup - limInf ; int suma = 0; for ( int i = 0; i < conteo . length ; i ++) { Usuario . m e n s a j e C o n s o l a (( i + limInf ) + " : " + conteo [ i ]); suma = suma + conteo [ i ]; } Usuario . m e n s a j e C o n s o l a( " Suma : " + suma ); } }

IIC1103 Cap tulo 6: Arreglos

14

Problema 8: Mejor Ubicacin o


Enunciado Implemente el mtodo public int[] buscarMejorUbicacion(int[][] plano, int tam). e El primer parmetro es un arreglo bidimensional que representa un plano, donde cada casilla del arreglo a indica la calidad asignada a esa posicin en el plano. El mtodo debe buscar la submatriz cuadrada de lado o e tam, cuya calidad sea la mxima. Debe retornar la ubicacin de la casilla superior izquierda (la y columna). a o En otras palabras, si tam es 2, debe buscar la matriz de 2x2 dentro del plano, cuya suma de las casillas es mayor. Si hay ms de una empatada, debe retornar cualquiera. a Asuma que el arreglo bidimensional siempre es regular (todas las las tienen el mismo nmero de columnas). u Ejemplo: -1 2 0 1 -3 5 1 -3 -2 2 0 6 7 2 8 3 -3 -2 1 -2 7 6 11 0 4 -3 -4 -6 1 0

Si tam fuera 2, el mtodo debe retornar el arreglo {0, 3}, ya que es la posicin donde comienza la matriz de e o 2x2, cuya suma es mayor (13). En cambio si tam fuera 3, el mtodo debe retornar el arreglo {0, 2}, dado que e es la mayor suma (35). Criterios de solucin o Lo primero que tenemos que hacer es recorrer la matriz por completo. Para eso utilizamos un doble ciclo pero considerando que para no pasarnos de los lmites de la matriz tenemos que llegar a length-tam. Dentro de este ciclo tenemos que recorrer la submatriz de tamao tam, utilizando tambin un doble ciclo y calculando n e la suma de sus posiciones. Luego, si esa suma es mayor que la encontrada hasta el momento actualizamos el valor de la suma mayor y el valor de los ndices donde comienza la submatriz. Posible solucin o
public int [] b u s c a r M e j o r U b i c a c i o n( int [][] plano , int tam ) { int [] indices = { -1 , -1 }; int max = 0; for ( int i = 0; i <= plano . length - tam ; i ++) { for ( int j = 0; j <= plano [ i ]. length - tam ; j ++) { int suma = 0; for ( int k = i ; k < i + tam ; k ++) { for ( int m = j ; m < j + tam ; m ++) { suma += plano [ k ][ m ]; } } if ( indices [0] == -1 || suma > max ) { max = suma ; indices [0] = i ; indices [1] = j ; } } } return indices ; }

IIC1103 Cap tulo 6: Arreglos

15

Problema 9: Output Desconocido


Enunciado Indique el output que aparece en consola al ejecutar el siguientes cdigo: o
public class ClassA { private int id ; private String texto ; public ClassA ( int n , String t ) { id = n ; texto = t ; } public int getId (){ return id ; } public String getTexto (){ return texto ; } public void a g r e g a r T e x t o( String t ) { texto = texto + t ; } public ClassA copia () { return new ClassA ( id , texto ); } } public class ClassB { private ClassA [] listaA ; public ClassB ( int n , int id ) { listaA = new ClassA [ n ]; for ( int i = 0; i < listaA . length - 1; i ++) { listaA [ i ] = new ClassA ( id , " T " + i ); id = id + 1; } } public void agregar ( ClassA a ) { listaA [ listaA . length -1] = a ; } public ClassA getA ( int i ) { return listaA [ i ]; } public String ver () { String texto = " texto : " ; for ( int i = 0; i < listaA . length ; i ++) { if ( listaA [ i ] != null ) texto = texto + listaA [ i ]. getTexto () + " " ; } return texto ; } } import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { int x = 1; ClassB b1 = new ClassB (4 , x ); ClassB b2 = new ClassB (4 , x + 1); Usuario . m e n s a j e C o n s o l a( " L1 : " + b1 . ver ()); Usuario . m e n s a j e C o n s o l a( " L2 : " + b2 . ver ()); b1 . agregar ( b2 . getA (2)); ClassA a1 = b1 . getA (3); if ( a1 . getTexto (). equals ( b2 . getA (2). getTexto ())) { a1 . a g r e g a r T e x t o( " S " ); } else { a1 . a g r e g a r T e x t o( " N " ); } Usuario . m e n s a j e C o n s o l a( " L3 : " + b1 . ver ()); Usuario . m e n s a j e C o n s o l a( " L4 : " + b2 . ver ()); ClassA a2 = b1 . getA (3). copia (); a2 . a g r e g a r T e x t o( " P " + b2 . getA (1). getId ()); if ( a2 == b2 . getA (2)) { a2 . a g r e g a r T e x t o( " S " ); } else if ( a2 . getId () == b2 . getA (2). getId ()) { a2 . a g r e g a r T e x t o( " N " ); } b2 . agregar ( a2 ); Usuario . m e n s a j e C o n s o l a( " L5 : " + b1 . ver ()); Usuario . m e n s a j e C o n s o l a( " L6 : " + b2 . ver ()); } }

IIC1103 Cap tulo 6: Arreglos

16

Criterios de solucin o En ste tipo de problemas es buena opcin escribir a un lado una tabla con las variables, arreglos y objetos, e o e ir anotando los cambios l nea a l nea, realizando una especie de debug manual. Se debe ser bastante sistemtico para no equivocarse, y cuidar interpretar correctamente los cambios en las variables, arreglos y a en los objetos. Posible solucin o L1:texto: L2:texto: L3:texto: L4:texto: L5:texto: L6:texto: T0 T0 T0 T0 T0 T0 T1 T1 T1 T1 T1 T1 T2 T2 T2 T2S T2S T2 T2S T2S T2SP3N

IIC1103 Cap tulo 6: Arreglos

17

Problema 10: Admin Palabras


Enunciado Existe la clase AdminPalabras la cual posee una lista de palabras. Esta clase posee un mtodo ContarPalabrasPosibles e el cual recibe un String y retorna la cantidad de palabras de la lista que son posibles de formar con las letras del String recibido, cuidando que cada letra se puede usar una sola vez. Usted debe implementar el mtodo ContarPalabrasPosibles de la clase AdminPalabras. A continuacin e o se presenta un esquema de esta clase, usted no puede modicar los atributos de la clase, ni cambiar la rma del mtodo. Si lo desea, puede agregar nuevos mtodos a la clase. e e
public class A d m i n P a l a b r a s { private String [] l i s t a P a l a b r a s; public A d m i n P a l a b r a s( String [] lista ) { l i s t a P a l a b r a s = lista ; } public int C o n t a r P a l a b r a s P o s i b l e s( String letras ) {...} }

. A continuacin se muestra un ejemplo de un main que utiliza esta clase y el output que produce. o
public static void main ( String [] args ) { String [] lista = { " auto " , " pato " , " palo " , " poto " , " amar " , " amor " , " loca " , " loco " , " polo " , " poco " , " poca " , " rota " , " roto " }; A d m i n P a l a b r a s admin = new A d m i n P a l a b r a s( lista ); String [] letras = { " escalopa " , " a u t o m o t o r" , " p e r c a t a d o" }; for ( int i = 0; i < letras . length ; i ++) { int cont = admin . C o n t a r P a l a b r a s P o s i b l e s( letras [ i ]); Usuario . m e n s a j e C o n s o l a( letras [ i ] + " : " + cont ); } }

. Output: escalopa: 3 automotor: 4 percatado: 3 Criterios de solucin o Para implementar el mtodo que nos piden necesitamos primero declarar una variable para ir contando. e Luego recorremos todas las palabras en la lista (con un f or por ejemplo) y para cada una revisamos si es posible formarla con las letras recibidas. Para esto, dentro del ciclo que recorre la lista, creamos un arreglo para saber que letras ya hemos utilizado, donde el largo del arreglo es el nmero de letras disponibles y en u cada posicin del arreglo guardamos un true si esa letra ya se us o false si todav no se ha utilizado. Luego o o a recorremos todas las letras de la palabras y vemos si estn en la letras disponibles sin haber sido usadas. a Cuando encontramos una letra la marcamos como no disponible. As, si pudimos conseguir todas las letras aumentamos el contador en uno. Finalmente retornamos el contador.

IIC1103 Cap tulo 6: Arreglos

18

Posible solucin o
public class A d m i n P a l a b r a s { private String [] l i s t a P a l a b r a s; public A d m i n P a l a b r a s( String [] lista ) { l i s t a P a l a b r a s = lista ; } public int C o n t a r P a l a b r a s P o s i b l e s( String letras ) { // Creamos una variable para ir contando int contador = 0; // R e c o r r e m o s todas las palabras en la lista y para cada una r e v i s a m o s // si es posible formarla con las letras r e c i b i d a s for ( int i = 0; i < l i s t a P a l a b r a s. length ; i ++) { // Creamos un arreglo para saber que letras ya hemos utilizado , // lo i n i c i a m o s en false boolean [] usadas = new boolean [ letras . length ()]; for ( int j = 0; j < usadas . length ; j ++) { usadas [ j ] = false ; } // R e c o r r e m o s todas las letras de la palabra y vemos si estan en las // letras d i s p o n i b l e s sin haber sido usadas boolean e s P o s i b l e = true ; for ( int j = 0; j < l i s t a P a l a b r a s[ i ]. length (); j ++) { boolean e n c o n t r a d a = false ; // Buscamos la letra entre las d i s p o n i b l e s for ( int k = 0; k < letras . length () && ! e n c o n t r a d a; k ++) { if (! usadas [ k ] && l i s t a P a l a b r a s[ i ]. charAt ( j ) == letras . charAt ( k )) { // E n c o n t r a m o s la letra , la marcamos como u t i l i z a d a e n c o n t r a d a = true ; usadas [ k ] = true ; } } if (! e n c o n t r a d a) { // Indica que la letra no fue e n c o n t r a d a entre las d i s p o n i b l e s e s P o s i b l e = false ; } } // R e v i s a m o s si fue posible c o n s e g u i r todas las letras if ( e s P o s i b l e) { contador ++; } } return contador ; } }

IIC1103 Cap tulo 6: Arreglos

19

Problema 11: El juego de la vida


Enunciado El juego de la vida es un juego de cero jugadores inventado por el matemtico John Conway en 1970. ste se a e juega en una grilla de clulas cuadradas (como un tablero de ajedrez) donde cada posicin del tablero tiene e o dos opciones, o tiene una clula o no. El objetivo de este juego (visto de una manera muy supercial) es e simular la vida, por esta misma razn hay reglas para determinar la supervivencia y muerte de las clulas. o e Estas reglas son: Una clula rodeada de menos de 2 clulas muere de soledad. e e

Una clula rodeada de 2 o 3 clulas sobrevive. e e

Una clula rodeada de ms de 3 celular muere por sobrepoblacin. e a o

En un espacio sin clulas solamente aparece (nace) una si es que est rodeada por exactamente 3 e a clulas. e

Usted debe crear un programa que simule este juego. Debe mostrar el tablero en consola donde se deben representar los espacios con clulas con unos y los vac con ceros. Las posiciones de cada clula deben e os e ser generadas aleatoriamente al empezar cada juego y en cada iteracin de ste se debe mostrar el tablero. o e Puede escoger cualquier tamao de tablero mientras sea mayor que 3x3. Para terminar, en cada iteracin n o debe preguntar al usuario si desea continuar. Ejemplo de tablero 8x8:

IIC1103 Cap tulo 6: Arreglos

20

Primera Iteracin o ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|1|0|1| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|1|1| ----------------|0|1|0|0|1|0|0|0| ----------------|0|1|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------Criterios de solucin o

Segunda Iteracin o ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| ----------------|0|0|0|0|0|0|0|0| -----------------

Es claro que la grilla del juego puede ser representado por una matriz. Entonces lo primero que debemos hacer es crear una matriz e inicializarla, esto lo hacemos con un doble for el cual tiene una probabilidad de 30 % de generar un clula en dicho espacio. e Luego, para revisar las condiciones, debemos contar la cantidad de unos que hay alrededor de cada una de las clulas, una vez hecho esto podemos decidir si la clula muere o vive. El problema que queda es que esta e e informacin no puede ser inmediatamente aplicada a nuestra matriz ya que debemos ocuparla, tal como est, o a para calcular la condicin de las otras clulas, es por esto que el siguiente estado de la matriz lo guardamos o e en una matriz auxiliar. Luego esta matriz es guardada en la matriz original y se repite el proceso.

Posible solucin o
import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void int numeroI = 8; int numeroJ = 8; int p r o b a b i l i d a d int [][] matriz = int [][] auxiliar main ( String [] args ) { // numero de columnas // numero de filas = 3; // p r o b a b i l i d a d de obtener un 1 en una posicion new int [ numeroI ][ numeroJ ]; // aqui g u a r a d a m o s las p o s i c i o n e s de las celulas = new int [ numeroI ][ numeroJ ]; // aqui g u a r d a m o s las p o s i c i o n e s nuevas

for ( int i = 0; i < numeroI ; i ++) { // creamos el tablero Usuario . m e n s a j e C o n s o l a( " - - - - - - - - - - - - - - - - -" ); for ( int j = 0; j < numeroJ ; j ++) { if ( A l e a t o r i o. entero (1 , 10) > p r o b a b i l i d a d) { // si es mayor que la p r o b a b i l i d a d no creamos una celula matriz [ i ][ j ] = 0; } else { matriz [ i ][ j ] = 1; } System . out . print ( " | " + matriz [ i ][ j ]); } Usuario . m e n s a j e C o n s o l a( " | " ); } Usuario . m e n s a j e C o n s o l a( " - - - - - - - - - - - - - - - - -" ); Usuario . m e n s a j e C o n s o l a( " \ n \ n \ n " ); while ( true ) { // itera hasta que hacemos un break

IIC1103 Cap tulo 6: Arreglos

21

for ( int i = 0; i < numeroI ; i ++) { // vamos iterando por la matriz for ( int j = 0; j < numeroJ ; j ++) { // cuenta la cantidad de celulas que rodean a una posicion int contador = 0; if ( i != 0 && j != 0) { // r e v i s a m o s que no estamos en la esquina superior // izquierda , ya que o si no no p o d r i a m o s ver si es // que tenemos una celula a en nuesta diagonal // arriba hacia la i z q u i e r d a if ( matriz [ i - 1][ j - 1] == 1) { // si es que hay una celula arriba a // mi i z q u i e r d a sumo 1 al contador contador ++; } } if ( i != 0) { // reviso que no este en el borde superior del tablero // ya que si estoy ahi no puedo mirar hacia la posicion // que esta arriba mio if ( matriz [ i - 1][ j ] == 1) { // si es que hay una celula arriba mio contador ++; // sumo 1 al contador } } if ( i != 0 && j != ( numeroJ - 1)) { // igual , pero esquina superior derecha if ( matriz [ i - 1][ j + 1] == 1) { contador ++; } } if ( j != numeroJ - 1) { // igual , pero borde derecho if ( matriz [ i ][ j + 1] == 1) { contador ++; } } if ( i != ( numeroI - 1) && j != ( numeroJ - 1)) { // igual pero esquina inferior derecha if ( matriz [ i + 1][ j + 1] == 1) { contador ++; } } if ( i != ( numeroI - 1)) { // igual pero borde inferior if ( matriz [ i + 1][ j ] == 1) { contador ++; } } if ( i != ( numeroI - 1) && j != 0) { // igual pero esquina inferior i z q u i e r d a if ( matriz [ i + 1][ j - 1] == 1) { contador ++; } } if ( j != 0) { // igual pero borde i z q u i e r d o if ( matriz [ i ][ j - 1] == 1) { contador ++; } } if ( matriz [ i ][ j ] == 0 && contador == 3) { // si es que en la posicion no habia una y el contador es tres auxiliar [ i ][ j ] = 1; // creamos una celula en la posicion } else if ( matriz [ i ][ j ] == 1 && ( contador == 2 || contador == 3)) { // si es que habia una y hay 2 0 3 celulas auxiliar [ i ][ j ] = 1; // creamos la celular } else { // en c u a l q u i e r otro caso e l i m i n a m o s la celula auxiliar [ i ][ j ] = 0; } } } for ( int i = 0; i < numeroI ; i ++) { // i m p r i m i m o s la matriz e i g u a l a m o s auxiliar a matriz Usuario . m e n s a j e C o n s o l a( " - - - - - - - - - - - - - - - - -" ); for ( int j = 0; j < numeroJ ; j ++) { matriz [ i ][ j ] = auxiliar [ i ][ j ]; auxiliar [ i ][ j ] = 0;

IIC1103 Cap tulo 6: Arreglos

22

System . out . print ( " | " + matriz [ i ][ j ]); } Usuario . m e n s a j e C o n s o l a( " | " ); } Usuario . m e n s a j e C o n s o l a( " - - - - - - - - - - - - - - - - -" ); Usuario . m e n s a j e C o n s o l a( " \ n \ n \ n " ); int c o n t i n u a r = Usuario . entero ( " Desea C o n t i n u a r? " ); if ( c o n t i n u a r == 0) { break ; } } } }

IIC1103 Cap tulo 6: Arreglos

23

Problema 12: Validando un Sudoku


Enunciado El objetivo del Sudoku es rellenar una cuadrcula de 9x9 celdas (81 casillas), dividida en 9 subcuadr culas de 3x3 casillas (estas subcuadr culas son conocidas como cajas o regiones) con las cifras del 1 al 9 manteniendo las siguientes restricciones: Dentro de una regin no puede repetirse ninguna cifra (cada regin tiene 9 celdas por lo que en cada o o regin deben estar las 9 cifras posibles). o Cada la dentro de la cuadr cula debe tener las 9 cifras posibles (como son 9 celdas por la, solamente debe haber una aparicin de cada cifra en esa la). o Cada columna dentro de la cuadr cula debe tener las 9 cifras posibles (como son 9 celdas por columna, solamente debe haber una aparicin de cada cifra en esa columna). o En la siguiente gura se muestra el tablero nal del Sudoku, siendo los valores alrededor del tablero, ndices que permiten identicar las las y las columnas.

Usted debe escribir el mtodo Validar que dado un tablero nal de Sudoku chequea si ste cumple con las e e reglas arriba enunciadas. boolean Validar(int[][] sudoku){...} Recuerde chequear que la matriz sea vlida, puede suponer que la matriz es regular y que ha sido inicializada, a pero debe chequear que tiene la cantidad correcta de las y columnas. Si lo considera conveniente, puede crear otros mtodos y clases que le permitan resolver el problema y que e sean llamados desde el mtodo Validar. e Criterios de solucin o Debemos ir revisando las condiciones de manera secuencial. Primero debemos comprobar que el tamao del n arreglo sea correcto. Luego pasaremos por todos los casilleros, revisando que el n mero est entre los valores u e permitidos (1 y 9), y no se encuentre repetido en la la o columna. Por ultimo revisaremos las submatrices de 3x3, comprobando que no se repitan nmeros. Si en cualquier caso una comprobacin falla, retornaremos u o false, si pasa todas las validaciones, retornaremos true.

IIC1103 Cap tulo 6: Arreglos

24

Posible solucin o
public static boolean Validar ( int [][] tabla ) { // C o m p r o b a m o s que el tamano sea el c o r r e s p o n d i e n t e if ( tabla . length != 9 || tabla [0]. length != 9) { return false ; } for ( int k = 1; k < 10; k ++) { // Elejimos un numero del 1 al 9 // Viajamos por una de las d i m e n s i o n e s del array for ( int i = 0; i < tabla . length ; i ++) { // S u p o n e m o s que el numero buscado no esta ni en las filas ni en las columnas // para cada columna y fila r e s p e c t i v a m e n t e e i n i c i a l m e n t e boolean e s t a f i l a s = false ; boolean e s t a c o l u m n a s = false ; for ( int j = 0; j < tabla [ i ]. length ; j ++) { // C o m p r o b a m o s que el numero de la tabla este entre 1 y 9 if ( tabla [ i ][ j ] < 1 || tabla [ i ][ j ] > 9) { return false ; } // V e r i f i c a m o s igualdad del numero en la tabla c o r r e s p o n d e // al buscado en las filas if ( tabla [ i ][ j ] == k ) { // Si estaba a n t e r i o r m e n t e retorna false , sino graba que esta if ( e s t a f i l a s) { return false ; } e s t a f i l a s = true ; } // V e r i f i c a m o s igualdad del numero en la tabla c o r r e s p o n d e // al buscado en las columnas if ( tabla [ j ][ i ] == k ) { // Si estaba a n t e r i o r m e n t e retorna false , sino graba que esta if ( e s t a c o l u m n a s) { return false ; } e s t a c o l u m n a s = true ; } } } // D i v i d i m o s la tabla en s u b m a t r i c e s de 3 x3 // R e c o r r e s m o s las s u b m a t r i c e s con los indices n y m for ( int n = 0; n < 3; n ++) { for ( int m = 0; m < 3; m ++) { // S u p o n e m o s que el numero buscado no esta en el cuadrado boolean e s t a c u a d r a d o = false ; // R e c o r r e m o s la s u b m e t r i z con los indices i y j , // d e p e n d i e n t e s de n y m for ( int i = 3 * n ; i < 3 * n + 3; i ++) { for ( int j = 3 * m ; j < 3 * m + 3; j ++) { // V e r i f i c a m o s igualdad del numero en la tabla // c o r r e s p o n d e al buscado la s u b m a t r i z if ( tabla [ j ][ i ] == k ) { // Si estaba a n t e r i o r m e n t e retorna false , // sino graba que esta if ( e s t a c u a d r a d o) { return false ; } e s t a c u a d r a d o = true ; } } } } } } return true ; }

IIC1103 Cap tulo 6: Arreglos

25

Problema 13: Suavizar Imagen


Enunciado Se le pide que disee un algoritmo de suavizado para trabajar con una clase Imagen ya existente. Esta posee n un atributo Pixel[][] bitmap que contiene todos los pixeles que conforman la imagen. Adems la clase a Pixel representa los pixeles segn su color RGB. Esta tiene los siguientes mtodos: u e Pixel(int r, int g, int b) // constructor con los valores RGB ingresados Pixel(int[] rgb) // constructor con los valores R = rgb [0], G = rgb[1], B = rgb[2] int getAzul() // retorna el valor entero asociado al color azul int getRojo() // retorna el valor entero asociado al color rojo int getVerde() // retorna el valor entero asociado al color verde El suavizado se realiza asignando a cada pixel el color promedio entre l y los 8 pixeles adyacentes. e Criterios de solucin o Primero observamos que debemos ver todos los pixeles que componen el bitmap, y para cada uno, revisar todos los pixeles adyacentes, y obtener el promedio de sus colores. Adems notamos que los pixeles de los a bordes tendrn menos pixeles adyacentes. a La forma de obtener el promedio de los colores es sumar determinada componente de todos los pixeles, y dividirlo por el nmero de pixeles, repitiendo el proceso con cada componente. u Tambin notamos que si realizamos las operaciones sobre la misma matriz, se modicar el resultado de los e a pixeles adyacentes del siguiente pixel, por lo que es mejor opcin realizar la tarea sobre un arreglo auxiliar. o

Posible solucin o
private void Suavizar () { Pixel [][] n u e v o B i t m a p = new Pixel [ bitmap . length ][ bitmap [0]. length ]; for ( int x = 0; x < n u e v o B i t m a p. length ; x ++) { for ( int y = 0; y < n u e v o B i t m a p [0]. length ; y ++) { int r , g , b , pixeles ; r = 0; g = 0; b = 0; pixeles = 0; for ( int i = x - 1; i < x + 1; i ++) { for ( int j = y - 1; j < y + 1; j ++) { if ( i >= 0 && i < n u e v o B i t m a p. length && j >= 0 && j < n u e v o B i t m a p [0]. length ) { pixeles ++; r = r + bitmap [ i ][ j ]. getRojo (); g = g + bitmap [ i ][ j ]. getVerde (); b = b + bitmap [ i ][ j ]. getAzul (); } } } r = r / pixeles ; g = g / pixeles ; b = b / pixeles ; n u e v o B i t m a p[ x ][ y ] = new Pixel (r , g , b ); } } bitmap = n u e v o B i t m a p; }

IIC1103 Cap tulo 6: Arreglos

26

Problema 14: Combinar Imgenes a


Enunciado Se requiere crear el mtodo FusionEspecial de la clase Imagen, la cual est conformada por una matriz de e a elementos de la clase Pixel. El mtodo FusionEspecial permite fusionar la imagen con otra imagen recibida e como parmetro, retornando una matriz de Pixel, que representa el resultado de la fusin. El siguiente es a o el encabezado del mtodo: e public Pixel[][] FusionEspecial(Imagen imagen, float ponderador) El algoritmo para fusionar ambas imgenes indica que cada pixel en la imagen resultante se calcula como la a ponderacin entre los pixeles de ambas imgenes, multiplicando el pixel ms fuerte por el ponderador y el o a a pixel ms dbil por la diferencia entre el ponderador y 1. El pixel ms fuerte ser aquel cuya suma de las 3 a e a a intensidades que lo forman es mayor. Podr amos expresar esto en la siguiente frmula: o R(i, j) = PM (i, j) + (1 ) Pm (i, j), a a e donde PM (i, j) corresponde al pixel ms fuerte y Pm (i, j) al ms dbil. La unica restriccin para que se pueda realizar la fusin es que ambas imgenes deben tener las mismas o o a dimensiones, de lo contrario el mtodo retorna null. e A continuacin se describen la clase Pixel y la clase Imagen. Usted debe solamente implementar el mtodo o e FusionEspecial de la clase Imagen sin cambiar nada ms de esta clase ni de la clase Pixel. a
public class Pixel { public Pixel ( int rojo , int verde , int azul ) {...} public Pixel ( int [] colores ){...} public int getRojo (){...} public int getVerde (){...} public int getAzul (){...} } public class Imagen { private Pixel [][] pixeles ; public Imagen ( Pixel [][] pixeles ) { this . pixeles = pixeles ; } public Pixel [][] F u s i o n E s p e c i a l( Imagen imagen , float p o n d e r a d o r) {...} public Pixel [][] g e t P i x e l e s() { return pixeles ; } }

Criterios de solucin o Lo primero que tenemos que hacer es revisar si las dimensiones son las mismas, ya que esto es una restriccin o de la fusin. Si no son iguales simplemente retornamos null. Si son iguales seguimos con el mtodo. o e Creamos la matriz de Pixeles donde guardaremos los resultados. Implementamos un doble ciclo que nos permita recorrer toda la matriz de resultados para ir llenando cada posicin. Luego calculamos dos sumas: la suma de todos los colores del pixel de la primera imagen y la suma o de todos los colores del pixel de la segunda imagen. Revisamos cul suma es mayor y segn esto aplicamos a u la frmula descrita en el enunciado para calcular el resultado y almacenarlo en la posicin de la matriz o o resultante. Finalmente retornamos la matriz resultante.

IIC1103 Cap tulo 6: Arreglos

27

Posible solucin o
public Pixel [][] F u s i o n E s p e c i a l( Imagen imagen , float p o n d e r a d o r) { Pixel [][] otros = imagen . g e t P i x e l e s (); // R e v i s a m o s si las d i m e n s i o n e s son las mismas , ya que esto es una // r e s t r i c c i o n de la fusion if ( pixeles . length != otros . length || pixeles [0]. length != otros [0]. length ) { return null ; } // Creamos la matriz de pixeles donde g u a r d a r e m o s los r e s u l t a d o s Pixel [][] r e s u l t a d o = new Pixel [ pixeles . length ][ pixeles [0]. length ]; // R e c o r r e m o s la imagen r e s u l t a n t e creando el color para cada pixel de esta for ( int i = 0; i < r e s u l t a d o. length ; i ++) { for ( int j = 0; j < r e s u l t a d o[ i ]. length ; j ++) { // Sumamos cada color para ver cual es mas fuerte int suma1 = pixeles [ i ][ j ]. getRojo () + pixeles [ i ][ j ]. getVerde () + pixeles [ i ][ j ]. getAzul (); int suma2 = otros [ i ][ j ]. getRojo () + otros [ i ][ j ]. getVerde () + otros [ i ][ j ]. getAzul (); int rojo , verde , azul ; if ( suma1 > suma2 ) { rojo = ( int ) ( pixeles [ i ][ j ]. getRojo () * p o n d e r a d o r + (1 - p o n d e r a d o r) * otros [ i ][ j ]. getRojo ()); verde = ( int ) ( pixeles [ i ][ j ]. getVerde () * p o n d e r a d o r + (1 - p o n d e r a d o r) * otros [ i ][ j ]. getVerde ()); azul = ( int ) ( pixeles [ i ][ j ]. getAzul () * p o n d e r a d o r + (1 - p o n d e r a d o r) * otros [ i ][ j ]. getAzul ()); } else { rojo = ( int ) ( otros [ i ][ j ]. getRojo () * p o n d e r a d o r + (1 - p o n d e r a d o r) * pixeles [ i ][ j ]. getRojo ()); verde = ( int ) ( otros [ i ][ j ]. getVerde () * p o n d e r a d o r + (1 - p o n d e r a d o r) * pixeles [ i ][ j ]. getVerde ()); azul = ( int ) ( otros [ i ][ j ]. getAzul () * p o n d e r a d o r + (1 - p o n d e r a d o r) * pixeles [ i ][ j ]. getAzul ()); } // A g r e g a m o s el pixel al r e s u l t a d o r e s u l t a d o[ i ][ j ] = new Pixel ( rojo , verde , azul ); } } return r e s u l t a d o; }

IIC1103 Cap tulo 6: Arreglos

28

Problema 15: Mquina de Bebidas a


Enunciado Una mquina expendedora de bebidas calientes vende 5 tipos de sta, caf, chocolate, cortado, capuccino a e e y moka. La mquina recibe las monedas del cliente, procesa la opcin elegida, y si es posible le entrega el a o producto, en conjunto con el vuelto correspondiente. La mquina acepta monedas de 10, 50, 100, 500, y a billetes de 1000 y 2000. La mquina solamente es capaz de dar vuelto si es posible hacerlo con la m a nima cantidad de monedas posibles (nunca se utilizan billetes para dar vuelto, slo monedas). Por ejemplo, si el o vuelto a dar son 1270, entonces la venta se realizar si y solo s la mquina posee al menos 2 monedas de a a 500, 2 monedas de 100, 1 moneda de 50 y 2 monedas de 10. Implemente la clase Maquina la cual debe representar a esta mquina expendedora. Su clase debe tener a al menos un constructor que reciba un arreglo con los precios de las 5 bebidas, e inicialice las cantidades iniciales para cada moneda, las cuales son 50 monedas de 10, 50, 100 y 500. Adems su clase debe tener el a mtodo Vender el cual debe tener la siguiente rma: e public int[] Vender(int[] ingresados, int producto) Donde ingresados representa a las monedas ingresadas por el cliente, en la posicin 0 estn las monedas o a de 10, en la 1 las de 50 y as sucesivamente en forma creciente (si no se ingresan monedas de alg n tipo, u entonces en la posicin que le corresponde en el arreglo hay un 0). El parmetro producto indica el o a ndice de la bebida seleccionada, en el mismo orden indicado anteriormente. Este mtodo debe retornar un arreglo e con las monedas (y billetes) que se deben dar de vuelto al usuario. En caso de no poder realizar la venta se retorna null. La compra no se puede realizar en caso que no sea posible dar el vuelto o en caso que el dinero ingresado no sea suciente para la bebida seleccionada. Puede agregar todos los mtodos y atributos que quiera a su clase. e Criterios de solucin o Para cumplir con lo que nos piden en el enunciado la clase Maquina deber tener como atributos un arreglo a que contenga la cantidad de cada una de las monedas que hay actualmente en la mquina y otro arreglo que a contenga los precios de las 5 bebidas calientes. Adems de esto la clase debe tener un constructor que reciba como parmetro los precios de las bebidas y a a los asigne al arreglo de precios que tiene como atributo. Adems debe inicializar la cantidad de monedas en a 50 (datos obtenidos del enunciado). Finalmente la clase debe tener un mtodo Vender. En este mtodo lo primero que hacemos es recorrer el e e arreglo con las monedas ingresadas por el usuario y calcular el precio total ingresado, para esto utilizamos un ciclo y multiplicamos el valor en cada posicin del arreglo por el valor de la moneda que representa la o posicin. Luego de esto actualizamos la cantidad de monedas que tiene la mquina recorriendo el arreglo de o a ingresados y sumando las cantidades al atributo que contiene las cantidades de cada moneda. A continuacin o tenemos que vericar si es factible hacer la venta, para eso revisamos que el dinero total ingresado sea mayor que el precio del producto y que contemos con dinero suciente para entregar el vuelto. Si se cumple esto entonces calculamos el vuelto y formamos el arreglo con las cantidades de cada moneda a devolver.

IIC1103 Cap tulo 6: Arreglos

29

Posible solucin o
public class Maquina { private int [] monedas ; private int [] v a l o r M o n e d a s = { 10 , 50 , 100 , 500 , 1000 , 2000 }; private int [] precios ; public Maquina ( int [] precios ) { this . precios = new int [5]; for ( int i = 0; i < this . precios . length ; i ++) { this . precios [ i ] = precios [ i ]; } monedas = new int [6]; for ( int i = 0; i < monedas . length - 2; i ++) { monedas [ i ] = 50; } } public int [] Vender ( int [] ingresados , int producto ) { int d i n e r o I n g r e s a d o = 0; for ( int i = 0; i < i n g r e s a d o s. length ; i ++) { d i n e r o I n g r e s a d o += i n g r e s a d o s[ i ]* v a l o r M o n e d a s[ i ]; } int m a x V u e l t o = d i n e r o I n g r e s a d o - masCaro (); for ( int i = 0; i < monedas . length ; i ++) { monedas [ i ] += i n g r e s a d o s[ i ]; } if ( v e r i f i c a r F a c t i b i l i d a d( m a x V u e l t o) && d i n e r o I n g r e s a d o >= precios [ producto ]) { return d e v o l v e r D i n e r o( d i n e r o I n g r e s a d o - precios [ producto ]); } else { for ( int i = 0; i < monedas . length ; i ++) { monedas [ i ] -= i n g r e s a d o s[ i ]; } return null ; } } public int masCaro () { int masCaro = precios [0]; for ( int i = 1; i < precios . length ; i ++) { if ( precios [ i ] > masCaro ) { masCaro = precios [ i ]; } } return masCaro ; } public boolean v e r i f i c a r F a c t i b i l i d a d( int monto ) { for ( int i = monedas . length - 1; i > 0; i - -) { if ( monto / v a l o r M o n e d a s[ i ] > monedas [ i ]) { return false ; } monto = monto % v a l o r M o n e d a s[ i ]; } return true ; } public int [] d e v o l v e r D i n e r o( int dinero ) { int [] vuelto = new int [ monedas . length ]; for ( int i = monedas . length - 1; i > 0; i - -) { vuelto [ i ] = dinero / v a l o r M o n e d a s[ i ]; monedas [ i ] -= vuelto [ i ]; dinero = dinero % v a l o r M o n e d a s[ i ]; } return vuelto ; } }

IIC1103 Cap tulo 6: Arreglos

30

Problema 16: Cdigo Misterioso o


Enunciado Para el siguiente cdigo, indique el output que aparecer en la Consola. o a
public class ClassA { private String id ; private ClassA hijo ; private int total ; public ClassA ( String n ) { id = n ; total = 0; } public void setHijo ( ClassA h ) { hijo = h ; } public ClassA getHijo () { return hijo ; } public String getId () { return id ; } public void aumentar ( int delta ) { a u m e n t a r D e s d e P a d r e( delta ); if ( hijo != null ) hijo . a u m e n t a r D e s d e P a d r e( delta ); } public void a u m e n t a r D e s d e P a d r e( int delta ) { total += delta ; } public int getTotal () { return total ; } } public static void main ( String [] args ) { ClassA [] l i s t a O b j e t o s = new ClassA [5]; for ( int i = 0; i < l i s t a O b j e t o s. length ; i ++) { l i s t a O b j e t o s[ i ] = new ClassA ( " Objeto " + i ); if ( i % 2 == 1) { l i s t a O b j e t o s[ i ]. setHijo ( l i s t a O b j e t o s[ i - 1]); } l i s t a O b j e t o s[ i ]. aumentar ( i ); } for ( int i = 0; i < l i s t a O b j e t o s. length ; i ++) { if ( l i s t a O b j e t o s[ i ]. getTotal () == 1) { Usuario . m e n s a j e C o n s o l a( " L1 : " + l i s t a O b j e t o s[ i ]. getId ()); } } for ( int i = 0; i < l i s t a O b j e t o s. length ; i ++) { if ( l i s t a O b j e t o s[ i ]. getHijo () == null ) { l i s t a O b j e t o s[ i ]. setHijo ( l i s t a O b j e t o s[( i + 2) % l i s t a O b j e t o s. length ]); } } for ( int i = 0; i < l i s t a O b j e t o s. length ; i ++) { l i s t a O b j e t o s[ i ]. aumentar ( l i s t a O b j e t o s[ i ]. getHijo (). getHijo (). getTotal ()); } for ( int i = 0; i < l i s t a O b j e t o s. length ; i ++) { Usuario . m e n s a j e C o n s o l a( " L2 : " + l i s t a O b j e t o s[ i ]. getId () + " - Total : " + l i s t a O b j e t o s[ i ]. getTotal ()); } }

IIC1103 Cap tulo 6: Arreglos

31

Criterios de solucin o En ste tipo de problemas es buena opcin escribir a un lado una tabla con las variables, arreglos y objetos, e o e ir anotando los cambios l nea a l nea, realizando una especie de debug manual. Se debe ser bastante sistemtico para no equivocarse, y cuidar interpretar correctamente los cambios en las variables, arreglos y a en los objetos. Posible solucin o L1: L1: L2: L2: L2: L2: L2: Objeto0 Objeto1 Objeto0 Objeto1 Objeto2 Objeto3 Objeto4

Total: Total: Total: Total: Total:

14 24 33 17 28

IIC1103 Cap tulo 6: Arreglos

32

Problema 17: RunningUC


Enunciado No slo el estudio hace al estudiante. Tambin es importante la vida universitaria. Dentro de sta, la activio e e dad deportiva es algo que deber amos tener siempre en mente. En este problema se le pide que realice un programa en Java que maneja la inscripcin (de manera simplio cada) del ya tradicional evento RunningUC1 . Para esto, se le entregan las clases P rincipal y Alumno, y ud. debe completar los mtodos correspondientes en la clase BBDD. e Considere que la informacin a desplegar debe ser lo ms clara posible. En particular, el mtodo inf oInscritoN () o a e deber mostrar un mensaje tipo a Corredor Numero: 1 | Nombre: Ricardo | Edad: 23 | Categoria: Elite| avisando si el corredor no existe. Es decir, complete:
public class BBDD { public void agregar ( Corredor al ) {...} // agrega un nuevo corredor al arreglo public String i n f o I n s c r i t o N( int i ) {...} // muestra la i n f o r m a c i o n del i - esimo inscrito public String m o s t r a r I n s c r i t o s() {...} // muestra todos los i n s c r i t o s }

sin modicar:
public class Corredor { // [ A T R I B U T O S] private String nombre ; // nombre del corredor private int edad ; // su edad private int c a t e g o r i a; // 5 para 5k , 10 para 10 k , 11 para elite // [ METODOS ] // C o n s t r u c t o r public Corredor ( String nombre , int edad , int c a t e g o r i a) { this . nombre = nombre ; this . edad = edad ; this . c a t e g o r i a = c a t e g o r i a; } // getters public int g e t C a t e g o r i a() { return c a t e g o r i a; } public int getEdad () { return edad ; } public String g e t N o m b r e() { return nombre ; } }

1 para

esto y ms visite www.runninguc.cl, o dir a jase a deportes

IIC1103 Cap tulo 6: Arreglos

33

import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { /* * Programa para manejar la i n s c r i p c i o n para una corrida */ public static void main ( String [] args ) { // String con los mensajes a mostrar String b i e n v e n i d a = " B i e n v e n i d o a la i n s c r i p c i o n de soporte para el R u n n i n g U C" + " \ nMas i n f o r m a c i o n en www . r u n n i n g u c. cl " ; String d e s p e d i d a = " Nos vemos \ n ( mas info en www . r u n n i n g u c. cl ) " ; String p e d i r N o m b b r e = " Ingrese el nombre " , p e d i r E d a d = " Ingrese la edad " ; String p e d i r C a t e g o r i a = " Ingrese la c a t e g o r i a: " + " \ n 1] 5 K \ n 2] 10 K \ n 3] Elite " ; String menu = " Ingrese una opcion : " + " \ n0 ) Salir \ n1 ) I n s c r i b i r\ n2 ) Mostrar i n f o r m a c i o n de un corredor \ n3 ) Mostrar i n s c r i t o s" ; BBDD bd = new BBDD (); // creamos la base de datos ( i n i c i a l m e n t e vacia ) int opcion ; Usuario . mensaje ( b i e n v e n i d a); do { opcion = Usuario . entero ( menu ); // pedimos una opcion while ( opcion < 0 || opcion > 3){ // la v a l i d a m o s Usuario . mensaje ( " Opcion i n c o r r e c t a! " ); opcion = Usuario . entero ( menu ); } switch ( opcion ) { // hacemos lo que se pide case 0: { Usuario . mensaje ( d e s p e d i d a); break ;} // Salir case 1: { // I n s c r i b i r // pedimos el nombre String nombre = Usuario . texto ( p e d i r N o m b b r e); // pedimos la edad int edad = Usuario . entero ( p e d i r E d a d); while ( edad < 0) { edad = Usuario . entero ( p e d i r E d a d );} // v a l i d a m o s que sea >0 // pedimos la c a t e g o r i a int c a t e g o r i a = Usuario . entero ( p e d i r C a t e g o r i a); // v e r i f i c a m o s que este entre 1 y 3 while ( c a t e g o r i a < 1 || c a t e g o r i a > 3 ) { c a t e g o r i a = Usuario . entero ( p e d i r C a t e g o r i a); } Corredor al = new Corredor ( nombre , edad , c a t e g o r i a); // lo creamos bd . agregar ( al ); // lo a g r e g a m o s break ; } case 2: { // Pedir i n f o r m a c i o n de un corredor int numero = Usuario . entero ( " Ingrese el numero del corredor : " ); while ( numero < 1 ) // v a l i d a m o s que sea >= 1 numero = Usuario . entero ( " Ingrese el numero del corredor : " ); // buscamos esa posicion . Partimos de 0 , asi que restamos 1 al numero Usuario . mensaje ( bd . i n f o I n s c r i t o N( numero -1)); break ; } case 3: { Usuario . m e n s a j e C o n s o l a( bd . m o s t r a r I n s c r i t o s ()); break ;} // Mostrar todos } } while ( opcion != 0); } }

Criterios de solucin o Primero que todo, es importante reconocer los mtodos que debemos implementar y su forma: e public void agregar(Corredor al) {...} public String infoInscritoN(int i) {...} public String mostrarInscritos() {...} Adems, hay que llevar un registro con los corredores, i.e. es un arreglo de tipo Corredor, que como todos a los atributos ser privado: private Corredor[] inscritos. a Ahora bien, al momento de agregar un corredor se pueden tener 2 escenarios: El arreglo estaba vac y se crea uno nuevo (contiene slo al nuevo corredor) o, o El arreglo ya ten corredores. Es necesario crear uno nuevo, de tama o mayor en 1 al anterior, copiar a n cada elemento del arreglo antiguo al nuevo, y nalmente, copiar el nuevo elemento al nal de este nuevo IIC1103 Cap tulo 6: Arreglos 34

arreglo 2 . Por otro lado, la informacin que debemos mostrar emplea palabras para las categor de los corredores, o as por lo que debemos utilizar, por ejemplo, un switch para hacer la relacin. o Por ultimo, mostraremos un mensaje ad-hoc para la bienvenida, despedida, y en el caso que se pida infor macin y la lista est vac o e a. Posible solucin o
public class BBDD { private Corredor [] i n s c r i t o s; // agrega un nuevo corredor al arreglo public void agregar ( Corredor nuevo ) { // si el arreglo estaba vacio if ( this . i n s c r i t o s == null ) { i n s c r i t o s = new Corredor [1]; // creamos un arreglo de tamanio 1 i n s c r i t o s[0] = nuevo ; // ponemos al Corredor en la posicion 0 ( la // primera posicion ) } else { a g r a n d a r A r r e g l o (); // a g r a n d a m o s el arreglo // a g r e g a m o s al nuevo Corredor en la ultima casilla ( que la creamos // vacia ) this . i n s c r i t o s[ this . i n s c r i t o s. length - 1] = nuevo ; } } // hacemos el arreglo una casilla mas grande // es privado porque solo se debe llamar desde metodos de esta clase private void a g r a n d a r A r r e g l o() { // creamos un arreglo auxiliar de largo lenght +1 Corredor [] aux = new Corredor [ this . i n s c r i t o s. length + 1]; // copiamos cada Corredor al arreglo auxiliar for ( int i = 0; i < this . i n s c r i t o s. length ; i ++) { aux [ i ] = this . i n s c r i t o s[ i ]; } // la ultima posicion es null ( porque es 1 mas grande ) this . i n s c r i t o s = aux ; } // metodo para retornar la i n f o r m a c i o n del inscrito numero - esimo public String i n f o I n s c r i t o N( int numero ) { String info = " " ; // si la lista esta vacia if ( this . i n s c r i t o s == null ) { info = " No hay i n s c r i t o s. " ; // decimos que no hay i n s c r i t o s } else { // si la lista tiene por lo menos un inscrito // avisamos si el numero esta fuera del largo del arreglo if ( this . i n s c r i t o s. length <= numero ) { info += " No se e n c u e n t r a el numero s o l i c i t a d o" ; } else { // es una posicion valida , asi que o b t e n e m o s su i n f o r m a c i o n // llamamos a los gets () c o r r e s p o n d i e n t e s ( y a g r e g a m o s un "\ n ") info += " Corredor Numero : " + ( numero + 1) + " | " ; info += " Nombre : " + this . i n s c r i t o s[ numero ]. g e t N o m b r e() + " | " ; info += " Edad : " + this . i n s c r i t o s[ numero ]. getEdad () + " | " ; int c a t e g o r i a = this . i n s c r i t o s[ numero ]. g e t C a t e g o r i a (); String cat = " " ; // m o s t r a r e m o s la c a t e g o r i a como el string que // c o r r e s p o n d e switch ( c a t e g o r i a) { case 1: cat = " 5 K " ; break ; case 2: cat = " 10 K " ; break ; case 3: cat = " Elite " ; break ; } info += " C a t e g o r i a: " + cat + " | " ;
2 la

solucin que se muestra ac crea un mtodo para esto o a e

IIC1103 Cap tulo 6: Arreglos

35

} } return info ; // r e t o r n a m o s la i n f o r m a c i o n del inscrito } // metodo para mostrar todos los i n s c r i t o s que hay en ese momento public String m o s t r a r I n s c r i t o s() { String todos = " " ; // variable que guardara la i n f o r m a c i o n // si el arreglo es null if ( this . i n s c r i t o s == null ) { todos = " No hay i n s c r i t o s. " ; // quiere decir que no hay i n s c r i t o s } else { // hay por lo menos un inscrito // r e c o r r e m o s el arreglo for ( int i = 0; i < this . i n s c r i t o s. length ; i ++) { // le a g r e g a m o s la i n f o r m a c i o n del i - esimo inscrito todos += i n f o I n s c r i t o N( i ) + " \ n " ; } } return todos ; // r e t o r n a m o s la i n f o r m a c i o n total } }

IIC1103 Cap tulo 6: Arreglos

36

Problema 18: Naipes


Enunciado Uno de los nuevos casinos que entr en funcionamiento en las ultimas semanas le ha encargado que haga o una clase que le permita manejar cartas de un naipe ingls. Este naipe contiene 52 cartas, donde cada una e de ellas representa uno de los 13 valores posibles (i.e. 1 10, J, Q, K) combinado con alguna de las 4 pintas (i.e. corazn, pica, trbol y diamante). o e Una funcionalidad bsica es poder barajar las cartas, para ello se puede escoger dos posiciones en el naipe a al azar e intercambiarlos el nmero de veces que dena el usuario. Tambin es necesario poder repartir un u e n mero variable de cartas al usuario y actualizar el naipe (eliminando las cartas entregadas de el). u Usted deber implementar la clase Naipe deniendo sus atributos y los siguientes mtodos: a e public Naipe() constructor de la clase, inicializa el naipe con las 52 cartas posibles (no tendr Joa cker). public void barajar(int numero de intercambios) baraja escogiendo dos posiciones en el naipe al azar e intercambia las cartas, repite esta accin el n mero de veces denido por el parmetro o u a numero de intercambios. public String[] repartir(int n) toma las primeras n cartas del naipe y las retorna como un arreglo de String donde cada elemento representa una carta en el formato valor-pinta (e.g. 2-diamante, J-trbol). Actualiza el naipe eliminando estas cartas. Debe retornar null si no hay sucientes cartas e para repartir. Criterios de solucin o Lo primero que tenemos que hacer es declarar la clase y sus atributos, los cuales sern un arreglo que a represente las cartas y un entero para saber cuantas cartas quedan del mazo. Para el constructor lo que tenemos que hacer es crear cada una de las cartas del naipe. Como son muchas cartas lo mejor es utilizar un ciclo que vaya construyendo las cartas por pinta y por nmero. u Para el mtodo barajar tenemos que implementar un ciclo que se repita tantas veces como el nmero de e u intercambios ingresado por el usuario. Luego, dentro del ciclo, generamos dos nmeros aleatorios que sern u a las posiciones de los naipes que intercambiaremos. As cambiamos los naipes de las posiciones aleatorias, , cuidando guardar el valor del primer naipe en una variable auxiliar para no perderlo al hacer el intercambio. Para el mtodo repartir primero revisamos que haya sucientes cartas en el mazo. Si las hay formamos el e arreglo con las cartas a repartir y con un ciclo movemos las cartas restantes hacia el inicio del arreglo, para as eliminar las primeras y no volver a repartirlas. Actualizamos tambin el n mero de cartas del mazo y e u retornamos el arreglo de las repartidas.

IIC1103 Cap tulo 6: Arreglos

37

Posible solucin o
import i i c 1 1 0 3 P a c k a g e .*; public class Naipe { String [] mazo ; int n u m e r o _ c a r t a s; public Naipe () { n u m e r o _ c a r t a s = 52; mazo = new String [ n u m e r o _ c a r t a s]; String [] pinta = { " corazon " , " pica " , " trebol " , String [] n u m e r o _ s i m b o l o = { " 1 " , " 2 " , " 3 " , " 4 " , " 9 " , " 10 " , " J " , " Q " , " K " }; for ( int i = 0; i < n u m e r o _ s i m b o l o. length ; i ++) for ( int j = 0; j < pinta . length ; j ++) { mazo [ i * 4 + j ] = n u m e r o _ s i m b o l o[ i ] + " " + } } } public void barajar ( int n u m e r o _ d e _ i n t e r c a m b i o s) { if ( n u m e r o _ c a r t a s < 2) { return ; } String aux ; for ( int i = 0; i < n u m e r o _ d e _ i n t e r c a m b i o s; i ++) { int primero = A l e a t o r i o. entero (0 , n u m e r o _ c a r t a s - 1); int segundo = A l e a t o r i o. entero (0 , n u m e r o _ c a r t a s - 1); if ( primero != segundo ) { aux = mazo [ primero ]; mazo [ primero ] = mazo [ segundo ]; mazo [ segundo ] = aux ; } } } public String [] repartir ( int n ) { // n negativo o mayor que el numero de cartas en el mazo if ( n < 1 || n u m e r o _ c a r t a s < n ) { return null ; } // Arreglo con cartas r e p a r t i d a s String [] mano = new String [ n ]; // Copio las cartas en el arreglo mano for ( int j = 0; j < n ; j ++) { mano [ j ] = mazo [ j ]; } // Elimino cartas del mazo d e s p l a z a n d o las r e s t a n t e s hacia delante for ( int i = 0; i < n u m e r o _ c a r t a s - n ; i ++) { mazo [ i ] = mazo [ i + n ]; // copio } // O p c i o n a l m e n t e podra eliminar las r e p e t i d a s del final // A c t u a l i z o la cantidad de cartas del mazo numero_cartas = numero_cartas - n; return mano ; } }

" diamante " }; "5", "6", "7", "8", { pinta [ j ];

IIC1103 Cap tulo 6: Arreglos

38

Problema 19: Ocinas


Enunciado Una empresa tiene ocinas distribuidas en varios edicios y quiere desarrollar un software que permita monitorear la forma en la que distribuye el espacio en cada planta de stos. Para ello divide el espacio de e cada planta en varias ocinas, a cada una de las cuales debe asignarse un nombre y un tamao en metros n cuadrados. Sin embargo, las salas asignadas a una planta del edicio no pueden exceder el tamao total de n sta, ni se puede colocar ms de 20 ocinas por planta, por pequeas que sean, por un tema log e a n stico. Genere un programa que permita representar este problema. En particular, incluya cdigo en Java que al o ejecutar el siguiente main():
public static void main ( String [] args ) { // Defino el tamanio de cada uno de los pisos del edificio . int [] tamanos = { 120 , 120 , 80 }; Edificio s a n A g u s t i n = new Edificio ( " San Agustin " , tamanos ); // Agrego oficinas a un d e t e r m i n a d o piso , con un nombre y tamanio // asignado . s a n A g u s t i n. a g r e g a r O f i c i n a(0 , " Sala H1 " , 30); s a n A g u s t i n. a g r e g a r O f i c i n a(0 , " Sala H2 " , 30); s a n A g u s t i n. a g r e g a r O f i c i n a(0 , " Sala H3 " , 30); s a n A g u s t i n. a g r e g a r O f i c i n a(0 , " Banio " , 15); s a n A g u s t i n. a g r e g a r O f i c i n a(1 , " Finanzas " , 50); s a n A g u s t i n. a g r e g a r O f i c i n a(1 , " C u b i c u l o s" , 50); s a n A g u s t i n. a g r e g a r O f i c i n a(1 , " Sala que no cabe " , 50); // No hay espacio . s a n A g u s t i n. a g r e g a r O f i c i n a(2 , " Gerencia " , 80); s a n A g u s t i n. m o s t r a r E s t r u c t u r a(); }

Muestre el siguiente mensaje en consola:


D i r e c t o r i o del edificio San Agustin : El piso 1 contiene : - Sala H1 (30 mt2 ) - Sala H2 (30 mt2 ) - Sala H3 (30 mt2 ) - Banio (15 mt2 ) El piso 2 contiene : - Finanzas (50 mt2 ) - C u b i c u l o s (50 mt2 ) El piso 3 contiene : - Gerencia (80 mt2 )

Utilice todo su conocimiento para dar un buen diseo a su solucin. n o Criterios de solucin o Una posible solucin a este problema es implementar tres clases: Oficina, Piso y Edificio. o La clase Oficina como atributos deber tener el nombre y los metros cuadrados que ocupa, adems de un a a constructor que reciba estos valores y los asigne a los atributos. Adems deber tener los getters necesarios a a para obtenerlos. La clase Piso como atributos deber tener un arreglo de Ocinas (de largo 20 pues es el mximo nmero de a a u ocinas por piso), un entero para determinar el nmero de ocinas que realmente hay en el piso y tambin u e un entero para almacenar el nmero de metros cuadrados disponibles. Adems deber tener los siguientes u a a mtodos: e Constructor: Reciba como parmetro el mximo nmero de metros cuadrados que puede tener el piso a a u y cree el arreglo de ocinas. Mtodo agregarOficina: Revise que no se hayan completado las 20 ocinas y que todava queden e metros cuadrados. Si hay espacio crear una nueva ocina, agregarla al arreglo y actualizar el nmero u IIC1103 Cap tulo 6: Arreglos 39

de metros cuadrados disponibles. Mtodo mostrarEstructura: Recorra todas las ocinas con un ciclo y muestre para cada una su e nombre y el nmero de metros cuadrados que ocupa. u La clase Edificio deber tener como atributos el nombre del Edicio y un arreglo de Pisos. Adems debe a a tener los siguientes mtodos: e Constructor: Reciba como parmetro el nombre del Edicio y un arreglo con el tamao de cada uno de a n los pisos. En el mtodo debe crear el arreglo de pisos (segn el nmero de elementos que contenga el e u u arreglo de tamaos) y luego crear cada uno de los Pisos (con un ciclo) asignando el tamao correcto. n n Mtodo agregarOficina: Reciba como parmetros el e a ndice del piso, el nombre y los metros cuadrados. Revise que el ndice del piso es correcto y si es as llame al mtodo agregarOficina del Piso e correspondiente. Mtodo mostrarEstructura: Mostrar en pantalla el nombre del edicio y con un ciclo mostrar lo que e contiene cada piso, llamando al mtodo mostrarEstructura de cada piso. e Posible solucin o
public class Oficina { private String nombre ; private int mt2 ; public Oficina ( String nombre , int mt2 ) { this . nombre = nombre ; this . mt2 = mt2 ; } public int getMt2 () { return mt2 ; } public String g e t N o m b r e() { return nombre ; } } public class Piso { private Oficina [] piezas = new Oficina [20]; private int n u m P i e z a s = 0; private int m t 2 L i b r e s; public Piso ( int maxMt2 ) { piezas = new Oficina [20]; n u m P i e z a s = 0; m t 2 L i b r e s = maxMt2 ; } boolean a g r e g a r O f i c i n a( String nombre , int mt2 ) { if ( n u m P i e z a s == 20 || m t 2 L i b r e s < mt2 ) { return false ; } piezas [ n u m P i e z a s ++] = new Oficina ( nombre , mt2 ); m t 2 L i b r e s -= mt2 ; return true ; } void m o s t r a r E s t r u c t u r a() { for ( int i = 0; i < n u m P i e z a s; i ++) { System . out . println ( " \ t \ t - " + piezas [ i ]. g e t N o m b r e() + " ( " + piezas [ i ]. getMt2 () + " mt2 ) " ); } } }

IIC1103 Cap tulo 6: Arreglos

40

public class Edificio { private Piso [] pisos ; private String nombre ; public Edificio ( String nombre , int [] tamanos ) { this . nombre = nombre ; pisos = new Piso [ tamanos . length ]; for ( int i = 0; i < pisos . length ; i ++) { this . pisos [ i ] = new Piso ( tamanos [ i ]); } } boolean a g r e g a r O f i c i n a( int piso , String nombre , int mt2 ) { if ( piso < 0 || piso >= pisos . length ) { return false ; } return pisos [ piso ]. a g r e g a r O f i c i n a( nombre , mt2 ); } void m o s t r a r E s t r u c t u r a() { System . out . println ( " D i r e c t o r i o del edificio " + nombre + " : " ); for ( int i = 0; i < pisos . length ; i ++) { System . out . println ( " \ tEl piso " + ( i + 1) + " contiene : " ); pisos [ i ]. m o s t r a r E s t r u c t u r a(); } } }

IIC1103 Cap tulo 6: Arreglos

41

Problema 20: Venta Pasajes EBE


Enunciado La empresa de buses del estado (EBE) est realizando una promocin en la venta de pasajes. a o Para almacenar el costo de los recorridos entre ciudades, utiliza una matriz cuadrada donde cada ciudad tiene asociado un nmero que la identica (entre 1 y N , siendo N el n mero total de ciudades a las que u u puede llegar la empresa). El elemento (x, y) de la matriz representa el costo que tiene realizar un viaje desde la ciudad x a la ciudad y. Cuando no existe un recorrido entre estas ciudades se deja el costo en 1. Adems la empresa posee por cada recorrido entre dos ciudades un arreglo que indica los asientos libres y a ocupados. Esto se debe a que la empresa ha destinado una la completa del bus para esta promocin. o Para que una persona pueda obtener un pasaje debe dirigirse a la boletera y comprarlo. Esto signica que el cajero a la hora de vender debe vericar si hay algn recorrido desde la ciudad x a la ciudad y y adems u a si existe alg n asiento disponible. En caso de disponibilidad simplemente marcar el asiento como ocupado. u a En caso contrario informar al pasajero la no disponibilidad. a

1
2200

5000

2
3000

6
2500

1500 800 6000

1 2 3 4 5 6

1 -1 -1 -1 -1 -1 -1

2 5000 -1 -1 -1 -1 -1

3 -1 3000 -1 -1 1500 -1

4 -1 -1 6000 -1 -1 -1

5 -1 -1 -1 -1 -1 2500

6 2200 -1 -1 800 -1 -1

El grco de la izquierda muestra el esquema de recorridos para 6 ciudades, y a la derecha se muestra una a matriz que representa este esquema. En este ejemplo: - Existe un recorrido desde la ciudad 1 hasta la ciudad 2 y tiene costo 5000, pero no existe un recorrido desde la ciudad 2 hasta la ciudad 1 (costo es 1). Para esta pregunta se le pide implementar la clase Ruta para representar los recorrido, de acuerdo a las siguientes especicaciones: a) Los atributos de la clase son la matriz donde se debe almacenar el costo de los recorridos entre las ciudades y la matriz que indica la disponibilidad de asientos. b) Implemente el mtodo constructor de la clase Ruta. Este mtodo debe solicitar al usuario que ingrese e e la cantidad de ciudades. Luego debe solicitar el costo de viaje entre cada par de ciudades y almacenarlo en la matriz de costos denida en la clase. Recuerde tener vac la matriz de disponibilidad. Usted debe a pedirle al usuario que ingrese la cantidad de asientos disponibles en promocin, el cual es el mismo o para cada par de ciudades. c) Implemente un mtodo llamado costoRecorridoDirecto que retorne el costo de viaje entre dos ciudades. e Si el camino no existe el mtodo debe retornar 1 e imprimir el error. Nota: verique antes que exista e camino entre las dos ciudades. Por ejemplo: si observamos el esquema de recorridos no existe camino directo entre 4 y 1, pues para llegar a 4 antes debe recorrer las ciudades 2 y 3. Pero si existe camino directo entre 1 y 6 con costo 2200. IIC1103 Cap tulo 6: Arreglos 42

d) Implemente un mtodo ventaPasaje que determine si se puede o no vender un pasaje, esto slo si e o existe disponibilidad de asientos para realizar un viaje entre varias ciudades. El mtodo recibe como e parmetro un arreglo de enteros que representa las ciudades que forman la ruta. a Por ejemplo: para la ruta [1, 6, 5], verico que exista camino y disponibilidad de asientos. En ese caso vendo el pasaje. Caso contrario, para la ruta [1, 2, 3, 4, 5] no existe ruta debido a que para llegar a 5 antes deber pasar por 6. a Criterios de solucin o El enunciado es bastante estructurado y nos indica que hacer. Primero declaramos la clase Ruta con dos atributos: una matriz de dos dimensiones para almacenar el costo de los recorridos y otra matriz de tres dimensiones para indicar la disponibilidad de un asiento desde una ruta hacia otra. Luego implementamos los mtodos que nos piden: e Constructor: En este mtodo pedimos al usuario que ingrese el nmero de rutas y el nmero de asientos e u u disponibles. Con estos datos creamos la matriz de costos y la de disponibilidad. Luego, con un doble ciclo inicializamos la matriz de costos, pidiendo para cada casilla el valor al usuario del costo de ir de una ciudad a otra. Dentro del mismo ciclo inicializamos tambin la matriz de disponibilidad. e Mtodo costoRecorridoDirecto: Este mtodo debe recibir los e e ndices de las ciudades. Lo primero que hacemos es revisar que dichos ndices sean vlidos (no nos salgamos de la matriz de costos). Luego a obtenemos el valor en la posicin de la matriz que corresponde al costo entre ambas ciudades y si este o costo es -1 le avisamos al usuario. Si no, retornamos el costo que corresponde. Mtodo ventaPasaje: Recibe como parmetro un arreglo con las ciudades que forman la ruta. Lo e a primero que hacemos es un ciclo para recorrer el arreglo recibido como parmetro. Luego, dentro del a ciclo, revisamos si hay costo para ir de una ciudad a la siguiente en el arreglo (llamando al mtodo e costoRecorridoDirecto). Luego revisamos si hay disponibilidad. Para esto revisamos la matriz de disponibilidad segn las dos rutas, recorriendo en todos los posibles asientos de esas dos ciudades u hasta encontrar alguno que sea true. Si esto se cumple para todas las ciudades del arreglo entonces actualizamos la disponibilidad de asientos. Posible solucin o
import i i c 1 1 0 3 P a c k a g e .*; public class Ruta { private int [][] r e c o r r i d o s; private boolean [][][] d i s p o n i b i l i d a d; public Ruta () { int n = Usuario . entero ( " Ingrese numero de rutas : " ); int t = Usuario . entero ( " Ingrese numero de asientos d i s p o n i b l e s: " ); r e c o r r i d o s = new int [ n ][ n ]; d i s p o n i b i l i d a d = new boolean [ n ][ n ][ t ]; for ( int i = 0; i < n ; i ++) for ( int j = 0; j < n ; j ++) { r e c o r r i d o s[ i ][ j ] = Usuario . entero ( " Ingrese costo : " + i -1 + " ," + j -1); for ( int k = 0; k < t ; k ++) { if ( i == 5) { d i s p o n i b i l i d a d[ i ][ j ][ k ] = false ; } else { d i s p o n i b i l i d a d[ i ][ j ][ k ] = true ; } } } } public int c o s t o R e c o r r i d o D i r e c t o( int x , int y ) { x = x - 1; // por los indices y = y - 1;

IIC1103 Cap tulo 6: Arreglos

43

if ( x >= 0 && y >= 0 && x < r e c o r r i d o s. length && y < r e c o r r i d o s [0]. length ) { if ( r e c o r r i d o s[ x ][ y ] == -1) Usuario . m e n s a j e C o n s o l a( " No existe camino directo entre las ciudades . " ); return r e c o r r i d o s[ x ][ y ]; } return -1; } private boolean h a y D i s p o n i b i l i d a d( int i , int j ) { for ( int k = 0; k < d i s p o n i b i l i d a d [0][0]. length ; k ++) { if ( d i s p o n i b i l i d a d[ i ][ j ][ k ]) { return true ; } } Usuario . mensaje (" no hay d i s p o n i b i l i d a d de " + i -1 + " a " + j -1); return false ; } public void v e n t a P a s a j e( int [] x ) { int total = 0; boolean valida = true ; for ( int i = 0; i < x . length - 1 && valida ; i ++) { int costo = this . c o s t o R e c o r r i d o D i r e c t o( x [ i ] , x [ i + 1]); if ( costo > 0 && h a y D i s p o n i b i l i d a d( x [ i ] , x [ i + 1])) total = total + costo ; else valida = false ; } if ( valida ) { for ( int i = 0; i < x . length - 1; i ++) this . r e s t a r D i s p o n i b i l i d a d(i , i +1); } } private void r e s t a r D i s p o n i b i l i d a d( int i , int j ) { int k = 0; boolean n o E n c o n t r e = true ; while ( n o E n c o n t r e && k < d i s p o n i b i l i d a d [0][0]. length ) { if ( d i s p o n i b i l i d a d[ i ][ j ][ k ]) { n o E n c o n t r e = false ; d i s p o n i b i l i d a d[ i ][ j ][ k ]= false ; } k = k + 1; } } }

IIC1103 Cap tulo 6: Arreglos

44

Problema 21: Facebook


Enunciado Dados los problemas de privacidad que actualmente tiene Facebook, le han pedido a un grupo de programadores implementar un prototipo de red social para la universidad. La idea gruesa es poder almacenar una lista de contactos y luego almacenar cules de dichos contactos son amigos entre s a . Al repartir el trabajo se decidi que usted no va a escribir el main() del programa, sino proveer la funcionao lidad requerida de forma que est disponible para quien lo haga. Para ello, escriba las clases necesarias en e java que permitan la serie de operaciones mencionadas a continuacin: o Representar una lista de personas de un tamao mximo predenido, a entregar por el main(). n a Poder agregar un nuevo nombre a la lista de personas. Su mtodo debe ingresar una nueva persona e con ese nombre y retornar a cambio un entero que sirva como identicador unico para la persona en el sistema (para evitar problemas con nombres repetidos). Poder hacer que dos personas se vuelvan amigos. Para ello se proporcionan a la lista los dos identicadores correspondientes. Considere y valide lo siguiente: Que la amistad es rec proca, no puedo ser amigo de alguien sin que ste sea amigo m e o. Que una persona no puede ser amigo de s misma.

Que una persona podr tener un mximo de 200 amigos. a a Poder obtener una persona teniendo su identicador.

Poder pedirle a una persona que imprima en consola su red de amistades. La red de amistades est coma puesta no slo por sus amigos directos sino tambin por los amigos directos de sus amigos. o e No importa si una misma persona aparece ms de una vez en el listado (al ser amiga comn de a u dos o ms amigos). a Criterios de solucin o Posible solucin o
/* * * Clase que almacena un contacto . */ public class Contacto { private String nombre ; private int id ; private Contacto [] amigos ; private int n u m A m i g o s; /* * i n i c i a l i z a el contacto . I n i c i a l m e n t e se comienza con un numero base de * @param nombre * @param id */ public Contacto ( String nombreC , int idC ) { nombre = nombreC ; id = idC ; amigos = new Contacto [200]; n u m A m i g o s = 0; } /* * * Agrega un nuevo amigo . El metodo intenta evitar tener que definir un * arreglo muy largo . Por ende , parte de una base fija y va d u p l i c a n d o la * c a p a c i d a d cuando se queda sin espacio . * @param amigo El amigo a agregar . */ amigos .

La persona original no debe obviamente aparecer en la lista, pese a ser amiga de sus amigos.

IIC1103 Cap tulo 6: Arreglos

45

public void a g r e g a r A m i g o( Contacto amigo ) { // Evito agregar un amigo ya e x i s t e n t e . for ( int i = 0; i < n u m A m i g o s; i ++) { if ( amigos [ i ] == amigo ) { return ; } } // Asigno un nuevo amigo amigos [ n u m A m i g o s ++] = amigo ; } /* * * Imprime la red de este contacto , es decir , todos los amigos directos y * los amigos de estos amigos . */ public void i m p r i m i r R e d D e A m i g o s() { System . out . println ( " Red de amigos de " + nombre + " : " ); for ( int i = 0; i < n u m A m i g o s; i ++) { System . out . println ( " \t - " + amigos [ i ]. nombre ); for ( int j = 0; j < amigos [ i ]. n u m A m i g o s; j ++) { if ( amigos [ i ]. amigos [ j ] != this ) { System . out . println ( " \ t \t - " + amigos [ i ]. amigos [ j ]. nombre ); } } } } /* * * @return the nombre */ public String g e t N o m b r e() { return nombre ; } /* * * @return the id */ public int getId () { return id ; } /* * * @return the n u m A m i g o s */ public int g e t N u m A m i g o s() { return n u m A m i g o s; } } public class Facebook { private Contacto [] c o n t a c t o s; private int n u m C o n t a c t o s; /* * C o n s t r u c t o r , facebook parte sin gente */ public Facebook ( int maximo ) { c o n t a c t o s = new Contacto [ maximo ]; n u m C o n t a c t o s = 0; } /* * * Agrega un contacto con el nombre indicado y le asigna un id del sistema , * que es r e t o r n a d o */ public int a g r e g a r C o n t a c t o( String nombre ) { c o n t a c t o s[ n u m C o n t a c t o s] = new Contacto ( nombre , n u m C o n t a c t o s); return n u m C o n t a c t o s ++; } /* * * R e l a c i o n a a un contacto con otro , i n d i c a n d o que son amigos . La amistad * es b i d i r e c c i o n a l */ public void a g r e g a r A m i g o( int contacto , int amigo ) { if ( contacto < n u m C o n t a c t o s && amigo < n u m C o n t a c t o s && contacto != amigo ) { c o n t a c t o s[ contacto ]. a g r e g a r A m i g o( c o n t a c t o s[ amigo ]); c o n t a c t o s[ amigo ]. a g r e g a r A m i g o( c o n t a c t o s[ contacto ]);

IIC1103 Cap tulo 6: Arreglos

46

} } /* * Retorna el contacto pedido . */ public Contacto g e t C o n t a c t o( int id ) { return c o n t a c t o s[ id ]; } }

IIC1103 Cap tulo 6: Arreglos

47

Problema 22: Patrones Sala


Enunciado Muchas veces es necesario organizar las salas para controles e interrogaciones, de forma que se minimice la copia. Una de ellas es eliminar o habilitar algunos puestos de la sala, de forma que los alumnos se encuentren a mayor distancia de lo normal. Ud. deber implementar un programa que permita aplicar algunos patrones de ubicaciones de personas a a una sala en particular. Para la realizacin del ejercicio cuenta con las siguientes clases ya implementadas. No debe modicar la clase o Principal.
public class Sala { private int ancho ; private int largo ; private int [] r e p r e s e n t a c i o n S a l a; public Sala ( int _ancho , int _largo ) { ancho = _ancho ; largo = _largo ; r e p r e s e n t a c i o n S a l a = new int [ _ancho * _largo ]; for ( int i = 0; i < r e p r e s e n t a c i o n S a l a. length ; i ++) { r e p r e s e n t a c i o n S a l a[ i ] = 0; } } public int [] g e t R e p r e s e n t a c i o n S a l a() { return r e p r e s e n t a c i o n S a l a; } public int getLargo () { return largo ; } public int getAncho () { return ancho ; } public void i m p r i m i r R e p r e s e n t a c i o n S a l a() { System . out . println ( " PIZARRON " ); for ( int i = 0; i < r e p r e s e n t a c i o n S a l a. length ; i ++) { if ( i % ancho == 0) { System . out . println (); } if ( r e p r e s e n t a c i o n S a l a[ i ] == 1) { System . out . print ( " X " ); } else { System . out . print ( r e p r e s e n t a c i o n S a l a[ i ]); } System . out . print ( " " ); } System . out . println ( " \ n " ); } public int g e t I n d e x F i l a V e r t i c a l( int indexRep ) { return indexRep % ancho ; } public int g e t I n d e x F i l a H o r i z o n t a l( int indexRep ) { return indexRep / ancho ; } }

IIC1103 Cap tulo 6: Arreglos

48

import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { Patron [] _ p a t r o n e s = new Patron [4]; _ p a t r o n e s[0] = new Patron (1); _ p a t r o n e s[1] = new Patron (2); _ p a t r o n e s[2] = new Patron (3); _ p a t r o n e s[3] = new Patron (4); D i s t r i b u c i o n _dist = new D i s t r i b u c i o n( null , _ p a t r o n e s); int opcion = 0; while ( opcion != 5) { opcion = Usuario . entero (" Ingrese opcion :\ n1 : Crear sala \ n2 : Aplicar patron \ n " + " 3: D e s a p l i c a r patrones \ n4 : Ver info sala \ n5 : Salir " ); while ( opcion < 1 || opcion > 5) { opcion = Usuario . entero ( " OPCION INVALIDA \ nIngrese opcion :\ n1 : Crear sala \ n " + " 2: Aplicar patron \ n3 : D e s a p l i c a r patrones \ n4 : Ver info sala \ n5 : Salir " ); } switch ( opcion ) { case 1: _dist . setSala ( c r e a r S a l a()); _dist . getSala (). i m p r i m i r R e p r e s e n t a c i o n S a l a (); _dist . getSala (). i m p r i m i r I n f o S a l a (); break ; case 2: if ( _dist . getSala () != null ) { _dist . a p l i c a r P a t r o n( e s c o g e r P a t r o n ()); _dist . getSala (). i m p r i m i r R e p r e s e n t a c i o n S a l a (); _dist . getSala (). i m p r i m i r I n f o S a l a (); } else { Usuario . mensaje ( " Debe crear una sala para usar esta opcion " ); } break ; case 3: if ( _dist . getSala () != null ) { _dist . d e s a p l i c a r P a t r o n e s(); _dist . getSala (). i m p r i m i r R e p r e s e n t a c i o n S a l a (); _dist . getSala (). i m p r i m i r I n f o S a l a (); } else { Usuario . mensaje ( " Debe crear una sala para usar esta opcion " ); } break ; case 4: if ( _dist . getSala () != null ) { _dist . getSala (). i m p r i m i r R e p r e s e n t a c i o n S a l a (); _dist . getSala (). i m p r i m i r I n f o S a l a (); } else { Usuario . mensaje ( " Debe crear una sala para usar esta opcion " ); } break ; } } } public static int e s c o g e r P a t r o n() { int opcion = 0; opcion = Usuario . entero ( " Ingrese patron :\ n1 : Borrar filas h o r i z o n t a l e s impares \ n " + " 2: Borrar filas v e r t i c a l e s impares \ n3 : Eliminar en cruz \ n " + " 4: H a b i l i t a r puestos par / par o impar / impar " ); while ( opcion < 1 || opcion > 4) { opcion = Usuario . entero (" OPCION INVALIDA \ nIngrese patron :\ n " + " 1: Borrar filas h o r i z o n t a l e s impares \ n2 : Borrar filas v e r t i c a l e s impares \ n " + " 3: Eliminar en cruz \ n4 : H a b i l i t a r puestos par / par o impar / impar " ); } return opcion - 1; } public static Sala c r e a r S a l a() { int ancho = Usuario . entero ( " Ingrese el ancho de la sala " ); int largo = Usuario . entero ( " Ingrese el largo de la sala ( desde el pizarron al fondo ) " ); return new Sala ( ancho , largo ); } }

IIC1103 Cap tulo 6: Arreglos

49

El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Para completar el primer incremento, deber completar la implementacin de la clase Sala. A continuacin a o o se detallan los mtodos que deber tener esta clase para este incremento (algunos ya estn implementados): e a a 1. Sala(int ancho, int largo) Constructor de la clase. Recibe el ancho y el largo (desde el pizarrn o hasta atrs) que tiene la sala (en puestos). Este mtodo tambin inicializa un arreglo unidimensional a e e que representa a la sala, donde un 0 indica puesto disponible, y un 1 un puesto que no se puede usar. Tenga en cuenta que el tamao de este arreglo es ancho*largo. n 2. int[] getRepresentacionSala() Retorna el arreglo unidimensional que representa a la sala. 3. int getLargo() Retorna el largo (en puestos) de la sala. 4. int getAncho() Retorna el ancho (en puestos) de la sala. 5. void imprimirRepresentacionSala() Imprime en consola el estado de la sala. Indica donde est el a pizarrn, y los puestos deshabilitados estn marcados con una X. o a 6. int getIndexFilaVertical(int indexRep) Retorna el ndice de la vertical de la celda representacionSala[indexRep]. 7. int getIndexFilaHorizontal(int indexRep) Retorna el ndice de la horizontal de la celda representacionSala[indexRep]. Adems en este incremento deber implementar la clase Patron con los siguientes mtodos (ud. deber crear a a e a completamente esta clase): 1. Patron(int tipo) Constructor de la clase. Recibe el n mero que representa el tipo del patrn a u o aplicar. 2. void setTipo(int tipo) Setea el tipo de patrn. o 3. void getTipo(int tipo) Retorna el tipo de patrn. o 4. void aplicarPatron(Sala sala) Aplica a sala el patrn que tiene seteado. Los o ndices parten desde cero (la horizontal 0, la vertical 0). Los patrones que debe tener implementados son3 : tipo 1: deshabilitar las horizontales impares. Un ejemplo de aplicacin de este patrn ser (para o o a una sala de ancho 10 y largo 6, a la que no se le han aplicado patrones): PIZARRON 0 0 0 0 0 0 0 0 0 0 X X X X X X X X X X 0 0 0 0 0 0 0 0 0 0 X X X X X X X X X X 0 0 0 0 0 0 0 0 0 0 X X X X X X X X X X
3 Los ejemplos aqu mostrados son outputs volcados en consola del resultado de la aplicacin de los distintos patrones sobre o una sala. En este mtodo Ud. no debe implementar la impresin en pantalla, sino la asignacin correcta de los valores del arreglo e o o unidimensional que la representa.

IIC1103 Cap tulo 6: Arreglos

50

tipo 2: deshabilitar las verticales impares. Un ejemplo de aplicacin de este patrn ser (para o o a una sala de ancho 10 y largo 6, a la que no se le han aplicado otros patrones): PIZARRON 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X 0 X tipo 3: deshabilitar asientos en cruz (diagonales). Ejemplos de aplicacin de este patrn ser o o an: Para una sala de ancho 10 y largo 6, a la que no se le han aplicado otros patrones: PIZARRON X 0 0 0 0 0 0 0 0 X 0 X 0 0 0 0 0 0 X 0 0 0 X 0 0 0 0 X 0 0 0 0 0 X 0 0 X 0 0 0 0 0 0 0 X X 0 0 0 0 0 0 0 0 X X 0 0 0 0 Para una sala de ancho 3 y largo 6, a la que no se le han aplicado otros patrones: PIZARRON X 0 X 0 X 0 X 0 X X 0 X 0 X 0 X 0 X tipo 4: habilitar asientos donde los ndices de su posicin sean ambos pares, o ambos impares. o Ejemplo de aplicacin de este patrn ser o o a: Para una sala de ancho 10 y largo 6, a la que previamente se le aplicaron los patrones 1 y 2: PIZARRON 0 X 0 X 0 X 0 X 0 X X 0 X 0 X 0 X 0 X 0 0 X 0 X 0 X 0 X 0 X X 0 X 0 X 0 X 0 X 0 0 X 0 X 0 X 0 X 0 X X 0 X 0 X 0 X 0 X 0 En esta iteracin se le pide que implemente los patrones 1 y 2. o Tambin deber implementar por completo la clase Distribucion, la que deber poseer los siguientes mtoe a a e dos: 1. Distribucion(Sala sala, Patron[] patrones) Constructor de la clase. Recibe un objeto de tipo Sala y un arreglo de tipo Patron, con los patrones asociados a esta distribucin de asientos. o 2. void setSala(Sala sala) Setea la sala. 3. Sala getSala() Retorna la sala asociada a la distribucin. o 4. void aplicarPatron(int index) Aplica el patrn almacenado en patrones[index] a la sala o previamente seteada.

IIC1103 Cap tulo 6: Arreglos

51

Incremento 2 Para completar el segundo incremento, Ud. debe agregar los siguientes mtodos a la clase Sala: e 1. int getCapacidadResultante() Retorna el nmero de asientos disponibles (luego de haber apliu cado alg n patrn, el n mero de asientos disponibles var u o u a). 2. void imprimirInfoSala() Muestra en pantalla con un mensaje, cierta informacin de la sala: o ancho, largo, capacidad total, capacidad resultante luego de aplicar patrones. Adems deber implementar el patrn # 4, dentro del mtodo aplicarPatron(...) de la clase Patron. a a o e Incremento 3 Para completar el tercer incremento, Ud. debe agregar los siguientes mtodo a la clase Distribucion: e 1. void aplicarPatrones() Aplica TODOS los patrones asociados a distribucin a la sala previao mente seteada. 2. void desaplicarPatrones() Desaplica TODOS los patrones que se han aplicado a la sala de la distribucin. o Adems deber implementar el patrn # 3, dentro del mtodo aplicarPatron(...) de la clase Patron. a a o e Criterios de solucin o Posible solucin o
public class D i s t r i b u c i o n { private Sala sala ; private Patron [] patrones ; public D i s t r i b u c i o n( Sala sala , Patron [] patrones ) { this . sala = sala ; this . patrones = patrones ; } public void setSala ( Sala _sala ) { sala = _sala ; } public Sala getSala () { return sala ; } public void a p l i c a r P a t r o n e s () { for ( int i = 0; i < patrones . length ; i ++) { patrones [ i ]. a p l i c a r P a t r o n( sala ); } } public void d e s a p l i c a r P a t r o n e s() { for ( int i = 0; i < sala . g e t R e p r e s e n t a c i o n S a l a (). length ; i ++) { sala . g e t R e p r e s e n t a c i o n S a l a ()[ i ] = 0; } } public void a p l i c a r P a t r o n( int index ) { patrones [ index ]. a p l i c a r P a t r o n( sala ); } } public class Patron { private int tipo ; public Patron ( int _tipo ) {

IIC1103 Cap tulo 6: Arreglos

52

tipo = _tipo ; } public void setTipo ( int _tipo ) { tipo = _tipo ; } public int getTipo () { return tipo ; } public void a p l i c a r P a t r o n( Sala _sala ) { if ( tipo == 1) { // eliminar filas h o r i z o n t a l e s impares for ( int i = 0; i < _sala . g e t R e p r e s e n t a c i o n S a l a (). length ; i ++) { if ( _sala . g e t I n d e x F i l a H o r i z o n t a l( i ) % 2 != 0) { _sala . g e t R e p r e s e n t a c i o n S a l a()[ i ] = 1; } } } else if ( tipo == 2) { // eliminar filas v e r t i c a l e s impares for ( int i = 0; i < _sala . g e t R e p r e s e n t a c i o n S a l a (). length ; i ++) { if ( _sala . g e t I n d e x F i l a V e r t i c a l( i ) % 2 != 0) { _sala . g e t R e p r e s e n t a c i o n S a l a()[ i ] = 1; } } } else if ( tipo == 3){ // e l i m i n a c i o n cruz for ( int i = 0; i < _sala . g e t R e p r e s e n t a c i o n S a l a (). length ; i ++) { int f i l a V e r t i c a l = _sala . g e t I n d e x F i l a V e r t i c a l( i ); int f i l a H o r i z o n t a l = _sala . g e t I n d e x F i l a H o r i z o n t a l( i ); if ( f i l a V e r t i c a l == f i l a H o r i z o n t a l % _sala . getAncho () || _sala . getAncho () - 1 - f i l a V e r t i c a l == f i l a H o r i z o n t a l % _sala . getAncho ()) { _sala . g e t R e p r e s e n t a c i o n S a l a()[ i ] = 1; } } } else if ( tipo == 4) { // h a b i l i t a c i o n puestos par / par o impar / impar for ( int i = 0; i < _sala . g e t R e p r e s e n t a c i o n S a l a (). length ; i ++) { int f i l a V e r t i c a l = _sala . g e t I n d e x F i l a V e r t i c a l( i ); int f i l a H o r i z o n t a l = _sala . g e t I n d e x F i l a H o r i z o n t a l( i ); if ( f i l a V e r t i c a l % 2 == f i l a H o r i z o n t a l % 2) { _sala . g e t R e p r e s e n t a c i o n S a l a()[ i ] = 0; } } } } } import i i c 1 1 0 3 P a c k a g e .*; public class Sala { private int ancho ; private int largo ; private int [] r e p r e s e n t a c i o n S a l a; public Sala ( int _ancho , int _largo ) { ancho = _ancho ; largo = _largo ; r e p r e s e n t a c i o n S a l a = new int [ _ancho * _largo ]; for ( int i = 0; i < r e p r e s e n t a c i o n S a l a. length ; i ++) r e p r e s e n t a c i o n S a l a[ i ] = 0; } public int [] g e t R e p r e s e n t a c i o n S a l a() { return r e p r e s e n t a c i o n S a l a; } public int getLargo () { return largo ; }

IIC1103 Cap tulo 6: Arreglos

53

public int getAncho () { return ancho ; } public int g e t C a p a c i d a d R e s u l t a n t e() { int c a p a c i d a d = 0; for ( int i = 0; i < g e t R e p r e s e n t a c i o n S a l a (). length ; i ++) { if ( g e t R e p r e s e n t a c i o n S a l a ()[ i ] == 0) { c a p a c i d a d++; } } return c a p a c i d a d; } public void i m p r i m i r R e p r e s e n t a c i o n S a l a() { System . out . println ( " PIZARRON " ); for ( int i = 0; i < r e p r e s e n t a c i o n S a l a. length ; i ++) { if ( i % ancho == 0) { System . out . println (); } if ( r e p r e s e n t a c i o n S a l a[ i ] == 1) { System . out . print ( " X " ); } else { System . out . print ( r e p r e s e n t a c i o n S a l a[ i ]); } System . out . print ( " " ); } System . out . println ( " \ n " ); } public void i m p r i m i r I n f o S a l a() { Usuario . mensaje ( " ancho : " + ancho + " \ nlargo : " + largo + " \ n c a p a c i d a d original : " + ( ancho * largo ) + " \ n c a p a c i d a d luego de aplicar patrones : " + g e t C a p a c i d a d R e s u l t a n t e ()); } public int g e t I n d e x F i l a V e r t i c a l( int indexRep ) { return indexRep % ancho ; } public int g e t I n d e x F i l a H o r i z o n t a l( int indexRep ) { return indexRep / ancho ; } }

IIC1103 Cap tulo 6: Arreglos

54

Problema 23: Ventas Centro Comercial


Enunciado Usted deber implementar un programa que permita contabilizar las ventas realizadas por las tiendas en un a centro comercial. Ms espec a camente deber implementar las clases Mall y Tienda que permitan al mtodo a e main ya implementado, poder extraer informacin sobre las ventas del centro comercial y las tiendas. o Para la realizacin del ejercicio cuenta con la siguiente clase, la cual no debe modicar. o
import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { int m a x T i e n d a s = Usuario . entero ( " Ingrese el numero maximo de tiendas que puede " + " tener el mall . " ); Mall shopping = new Mall ( m a x T i e n d a s); int opcion = -1; while ( opcion != 0) { opcion = Usuario . entero (" Ingrese la opcion de lo que desea hacer : " + " \ n (1) Crear una nueva tienda " + " \ n (2) Realizar una compra " + " \ n (3) Ver el total de ventas del mall " + " \ n (4) Ver las tiendas cuyo promedio de ventas se e n c u e n t r a en un cierto rango " + " \ n (5) Ver cuantas ventas realizo la tienda con mas ventas " + " \ n (0) Salir " ); if ( opcion == 1) { int m a x V e n t a s = Usuario . entero ( " Ingrese el numero maximo de " + " ventas para la tienda . " ); if ( shopping . c r e a r T i e n d a( m a x V e n t a s)) { Usuario . mensaje ( " La tienda se creo con exito . " ); } else { Usuario . mensaje ( " No fue posible crear la tienda . " ); } } else if ( opcion == 2) { int n u m T i e n d a = Usuario . entero ( " Ingrese el numero de la tienda . " ); int monto = Usuario . entero ( " Ingrese el monto de la compra . " ); if ( shopping . r e a l i z a r C o m p r a( numTienda , monto )) { Usuario . mensaje ( " Compra r e a l i z a d a con exito . " ); } else { Usuario . mensaje ( " No fue posible realizar la compra . " ); } } else if ( opcion == 3) { Usuario . mensaje ( " Las ventas totales del mall son : " + shopping . t o t a l V e n d i d o M a l l ()); } else if ( opcion == 4) { double cantidad = Usuario . real ( " Ingrese la cantidad con la cual comparar . " ); double d i f e r e n c i a = Usuario . real ( " Ingrese la d i f e r e n c i a maxima p e r m i t i d a. " ); shopping . m o s t r a r C e r c a n o s( cantidad , d i f e r e n c i a); } else if ( opcion == 5) { Tienda m a s V e n t a s = shopping . m a s V e n t a s (); if ( m a s V e n t a s == null ) { Usuario . mensaje ( " Necesita agregar tiendas al mall . " ); } else { Usuario . mensaje ( " La tienda con mas ventas ha r e a l i z a d o " + m a s V e n t a s. g e t N u m V e n t a s() + " ventas . " ); } } } } }

El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 Para completar el primer incremento, deber implementar la clase Tienda por completo. A continuacin se a o detallan los mtodos que deber tener esta clase. e a

IIC1103 Cap tulo 6: Arreglos

55

1. Tienda(int maxVentas) Constructor de la clase. Recibe la cantidad mxima de ventas que puede a realizar la tienda. 2. int getNumVentas() Retorna la cantidad de ventas realizadas por la tienda. 3. boolean agregarVenta(int monto Agrega una nueva venta a la tienda, segn el monto recibido. u Retorna false si no es posible agregar la venta (ya se cumpli la cantidad mxima). o a 4. int totalVendido() Retorna el monto total de las ventas realizadas. 5. double promedioVentas() Retorna el promedio de las ventas realizadas. 6. int maxVenta() Retorna la venta realizada por la tienda con el mayor monto. Adems en este incremento deber implementar la clase Mall con los siguientes mtodos: a a e 1. Mall(int max) Constructor de la clase. Recibe la cantidad mxima de tiendas que puede haber en a el centro comercial. 2. boolean crearTienda(int maxVentas) Permite agregar una nueva tienda al centro comercial. Recibe como parmetro la cantidad mxima de ventas que puede realizar la nueva tienda. Retorna a a false en caso de que no sea posible agregar la nueva tienda (ya se tiene la cantidad mxima de tiendas a posibles). 3. boolean realizarCompra(int numTienda, int monto) Permite realizar una compra en una tienda determinada. Recibe el ndice de la tienda (la tienda 0 es la primera que se agreg, la tienda 1 es o la segunda y as sucesivamente), adems recibe el monto de la compra que se quiere realizar. Retorna a false en caso de no poder realizar la compra en la tienda. Incremento 2 Para completar el segundo incremento, su programa debe agregar los siguientes mtodos a la clase Mall: e 1. Tienda masVentas() Permite obtener la tienda que ha realizado mas ventas. Si no hay tiendas en el centro comercial retorna null. 2. int totalVendidoMall() Retorna el monto total de las ventas en el centro comercial, el cual se obtiene de la suma de las ventas totales de todas las tiendas. Incremento 3 Para completar el tercer incremento, su programa debe cumplir con los siguientes requisitos: 1. void mostrarCercanos(double cantidad, double diferencia) Muestra en la consola aquellas tiendas cuyo promedio de ventas se diferencia de cantidad en a lo ms diferencia. Al mostrar en la a consola se debe mostrar el ndice de la tienda y el promedio real de la tienda. Despus el mtodo debe e e mostrar en un mensaje la cantidad de tiendas que cumplieron con el requisito buscado. Criterios de solucin o Posible solucin o
public class Tienda { private int [] ventas ; private int v e n t a A c t u a l; public Tienda ( int m a x V e n t a s) { // Al comienzo no hay ventas v e n t a A c t u a l = 0;

IIC1103 Cap tulo 6: Arreglos

56

// I n i c i a l i z a m o s el arreglo donde g u a r d a r e m o s las ventas ventas = new int [ m a x V e n t a s]; } public int g e t N u m V e n t a s() { return v e n t a A c t u a l; } public boolean a g r e g a r V e n t a( int monto ) { if ( v e n t a A c t u a l == ventas . length ) { return false ; } ventas [ v e n t a A c t u a l] = monto ; v e n t a A c t u a l++; return true ; } public int t o t a l V e n d i d o() { // D e f i n i m o s una variable de a c u m u l a d o r int total = 0; // Sumamos todas las ventas que ya se han r e a l i z a d o for ( int i = 0; i < v e n t a A c t u a l; i ++) { total += ventas [ i ]; } return total ; } public double p r o m e d i o V e n t a s() { // Si no hay ventas se retorna 0 if ( v e n t a A c t u a l == 0) { return 0; } // El promedio estara dado por el total de ventas dividido en la // cantidad // de ventas r e a l i z a d a s double prom = t o t a l V e n d i d o(); prom = prom / v e n t a A c t u a l; return prom ; } public int maxVenta () { // D e f i n i m o s una variable donde g u a r d a r e m o s el maximo int max = 0; for ( int i = 0; i < v e n t a A c t u a l; i ++) { if ( ventas [ i ] > max ) { max = ventas [ i ]; } } return max ; } } import i i c 1 1 0 3 P a c k a g e .*; public class Mall { private Tienda [] tiendas ; private int t i e n d a A c t u a l; public Mall ( int max ) { t i e n d a A c t u a l = 0; // I n i c i a l i z a m o s el arreglo con el tamanio maximo tiendas = new Tienda [ max ]; } public boolean c r e a r T i e n d a( int m a x V e n t a s) { // R e v i s a m o s si aun se pueden agregar nuevas tiendas if ( t i e n d a A c t u a l == tiendas . length ) { return false ; } // A g r e g a m o s la nueva tienda en la posicion Actual tiendas [ t i e n d a A c t u a l] = new Tienda ( m a x V e n t a s); t i e n d a A c t u a l++; return true ;

IIC1103 Cap tulo 6: Arreglos

57

} public boolean r e a l i z a r C o m p r a( int numTienda , int monto ) { // R e v i s a m o s que la tienda sea valida if ( n u m T i e n d a >= t i e n d a A c t u a l) { return false ; } // R e t o r n a m o s el valor devuelto por el metodo agregar venta de la // clase tienda , ya que de no poder a g r e g a r s e mas ventas este debe // retornar // false . return tiendas [ n u m T i e n d a ]. a g r e g a r V e n t a( monto ); } public Tienda m a s V e n t a s() { // Buscamos la Tienda que tienes mas ventas r e a l i z a d a s // Si no hay tiendas r e t o r n a m o s null if ( t i e n d a A c t u a l == 0) { return null ; } Tienda max = tiendas [0]; // R e c o r r e m o s todas las tiendas para ver cual es la con mas ventas for ( int i = 1; i < t i e n d a A c t u a l; i ++) { if ( tiendas [ i ]. g e t N u m V e n t a s() > max . g e t N u m V e n t a s()) { max = tiendas [ i ]; } } return max ; } public int t o t a l V e n d i d o M a l l () { // Si no hay tiendas entonces no hay ventas if ( t i e n d a A c t u a l == 0) { return 0; } // D e f i n i m o s una variable quesirva de a c u m u l a d o r int total = 0; for ( int i = 0; i < t i e n d a A c t u a l; i ++) { total += tiendas [ i ]. t o t a l V e n d i d o (); } return total ; } public void m o s t r a r C e r c a n o s( double cantidad , double d i f e r e n c i a) { // D e f i n i m o s una variable para contar las tiendas que poseen la // d i f e r e n c i a indicada . int contador = 0; // R e c o r r e m o s todas las tiendas y m o s t r a m o s aquellas cuyo promedio // se d i f e r e n c i a en a lo mas la d i f e r e n c i a indicada con la cantidad // recibida . for ( int i = 0; i < t i e n d a A c t u a l; i ++) { // C a l c u l a m o s la d i f e r e n c i a entre el promedio de la tienda y la // cantidad // recibida . Le a p l i c a m o s valor absoluto para que no importe si es // positivo o negativo if ( Math . abs ( cantidad - tiendas [ i ]. p r o m e d i o V e n t a s()) <= d i f e r e n c i a) { contador ++; Usuario . m e n s a j e C o n s o l a( " La tienda " + i + " tiene un promedio de " + " ventas de " + tiendas [ i ]. p r o m e d i o V e n t a s ()); } } // M o s t r a m o s el mensaje resumen Usuario . mensaje ( " Se e n c o n t r a r o n " + contador + " tiendas cuyo promedio de " + " ventas se d i f e r e n c i a b a por a lo mas " + d i f e r e n c i a + " con respecto a " + cantidad ); } }

IIC1103 Cap tulo 6: Arreglos

58

Problema 24: MasterMind


Enunciado En este ejercicio usted deber construir el juego mundialmente conocido MasterMind (Toque y Fama). Para a esto cuenta con una clase que se encargar del manejo de la interfaz con el usuario, por lo que usted solaa mente deber preocuparse de la lgica del juego. La clase InterfazMasterMind mostrada a continuacin debe a o o utilizarla pero no modicarla
import i i c 1 1 0 3 P a c k a g e .*; /* * Clase que sirve como interfaz grafica simple del juego M a s t e r M i n d */ public class I n t e r f a z M a s t e r M i n d { /* * * Muestra el estado de un jugador y un menu de opciones * @param t a b l e r o J u e g o : el tablero del jugador * @param t a b l e r o A y u d a s : el tablero con las ayudas * @param i n t e n t o s F a l t a n t e s : la cantidad de intentos que le quedan por hacer * @return : opcion del usuario */ public int M o s t r a r E s t a d o J u g a d o r( int [][] tableroJuego , int [][] tableroAyudas , int i n t e n t o s F a l t a n t e s) { ... } /* * * Funcion que muestra en pantalla el codigo * @param codigo : el codigo */ public void M o s t r a r C o d i g o( int [] codigo ) { ... } /* * * Pide al usuario los numeros del codigo , y retorna un arreglo con ellos * @param rangoMax : el entero maximo que puede ingresar * @param c a n t N u m e r o s : la cantidad de numeros a pedir * @return */ public int [] O b t e n e r I n t e n t o( int rangoMax , int c a n t N u m e r o s) { ... } /* * * Revisa si un numero ya esta en un arreglo * @param num : el numero a revisar * @param intento : el arreglo * @return true si estaba , false si no */ public boolean YaEsta ( int num , int [] intento ) { ... } /* * * Arma un string con el tablero y lo retorna * @param t a b l e r o J u e g o : el tablero a mostrar ( el juego ) * @param t a b l e r o A y u d a s: el tablero con las ayudas * @return un string con el tablero r e p r e s e n t a d o */ private String g e t S t r i n g T a b l e r o( int [][] tableroJuego , int [][] t a b l e r o A y u d a s) { ... } }

. El juego consiste en que se genera un cdigo de un largo predeterminado de nmeros, y luego el usuario o u intenta adivinar el cdigo generado. Para ello ingresa secuencias de n meros del mismo largo que el cdigo. o u o Para cada secuencia el juego le indica la cantidad de toques y la cantidad de famas que obtuvo, ambos valores obtenidos de la comparacin del cdigo ingresado por el usuario con el cdigo secreto generado por el juego. o o o Una fama se produce cuando uno de los valores indicados por el usuario est justo en la misma posicin que a o el mismo valor en el cdigo secreto. Por su parte, un toque se produce cuando el cdigo del usuario contiene o o un valor que se encuentra en el cdigo secreto, pero no estn en la misma posicin. o a o Por ejemplo, si el cdigo fuera de largo 4, el cdigo secreto fuese {1, 2, 3, 4} y el usuario ingresa el cdigo o o o {2, 6, 3, 1}, se le debiera indicar al usuario que obtuvo una fama (producto de que el 3 se encuentra en ambos cdigos en la misma posicin), y 2 toques, provocados por los nmeros 1 y 2. o o u

IIC1103 Cap tulo 6: Arreglos

59

Para esta versin, el cdigo siempre contendr valores diferentes. o o a El jugador tendr un mximo de intentos para lograr adivinar, perdiendo el juego si no logra dar con el a a n mero. u El programa lo dividiremos en 3 subconjuntos incrementales. Le recomendamos no comenzar con el siguiente subconjunto hasta terminar y probar el funcionamiento correcto del subconjunto actual. Incremento 1 En este incremento deber crear los siguientes mtodos de la clase MasterMind. Esta clase representa a a e la lgica del juego. Debe contener atributos que permitan guardar el cdigo secreto, otros que permitan o o guardar los valores indicados por el usuario en los diferentes intentos, as como el n mero de toques y famas u en cada intento. Por ultimo, deber tener un objeto de la clase InterfazMasterMind, la cual se encargar de a a interactuar con el usuario. F jese en los parmetros que reciben los mtodos de la clase InterfazMasterMind a e para que se haga una idea de como puede guardar la informacin en su clase. o MasterMind() Constructor de la clase. void InicializarTablero(int maxIntentos, int largoCodigo) Mtodo que inicializa los atrie butos encargados de guardar los cdigos ingresados por el usuario, as como los resultados generados o por estos cdigos. Recibe como parmetros el n mero mximo de intentos y el largo del cdigo. o a u a o void GenerarCodigo(int largoCodigo, int rangoMax) Genera el cdigo que deber adivinar el o a usuario. Obtiene los nmeros de forma aleatoria y vericando que todos sean distintos. Recibe el largo u del cdigo y el valor mximo para cada nmero del cdigo (el m o a u o nimo siempre es 1). void IniciarJuego(int maxIntentos, int largoCodigo, int rangoMax) Permite comenzar a jugar, manteniendo el ciclo del juego. Debe inicializar el tablero as como calcular el cdigo. Luego debe o mostrar el tablero utilizando el mtodo MostrarEstadoJugador de la clase InterfazMasterMind. Este e mtodo retorna la opcin seleccionada por el usuario, de la cual solamente debe considerar la opcin 2 y e o o 3. La opcin 2 permite al usuario ver el cdigo, para lo cual se debe invocar el mtodo MostrarCodigo o o e de la Interfaz del juego. La opcin 3 indica que se debe salir del programa. o Adems debe crear el main del programa, el cual debe crear un MasterMind, pedir los valores al usuario para a el mximo de intentos, el largo del cdigo y el valor mximo de los nmeros (debe vericar que este ultimo a o a u sea mayor o igual al largo del cdigo). o Incremento 2 Debe agregar a la clase MasterMind el siguiente mtodo: e boolean Adivinar(int[] intento) Indica que el usuario desea adivinar el cdigo secreto. Recibe o como parmetro un arreglo con los valores indicados por el usuario, y retorna true en caso de adivinar a completamente el cdigo, o false en otro caso. Debe comparar el cdigo del usuario con el cdigo o o o secreto, calcular el nmero de toques y famas, guardndolos donde corresponda, y luego retorna el u a valor correspondiente. Recuerde que si el largo del cdigo es N , entonces en caso de tener N famas o indica que el usuario acert el cdigo. o o Incremento 3 Debe agregar al mtodo IniciarJuego la posibilidad de manejar la opcin 1 indicada por el usuario, la e o cual indica que desea adivinar el cdigo. Luego debe llamar al mtodo ObtenerIntento de la interfaz, para o e luego revisar el intento con el mtodo Adivinar. Luego si el usuario adivina se le debe mostrar un mensaje e IIC1103 Cap tulo 6: Arreglos 60

indicndole esto y terminar el programa. En caso de que no adivine debe revisarse si an le quedan intentos, a u si no le quedan se debe mostrar un mensaje indicndole que perdi. a o Criterios de solucin o Posible solucin o
import i i c 1 1 0 3 P a c k a g e .*; public class M a s t e r M i n d { private int [] codigo ; private int [][] t a b l e r o J u e g o; private int [][] t a b l e r o A y u d a s; private I n t e r f a z M a s t e r M i n d GUI ; private int n u m I n t e n t o s; /* * C o n s t r u c t o r */ public M a s t e r M i n d() { GUI = new I n t e r f a z M a s t e r M i n d(); n u m I n t e n t o s = 0; } /* * Metodo que i n i c i a l i z a los valores en el tablero del juego * @param m a x I n t e n t o s : numero maximo de intentos * @param l a r g o C o d i g o : numero de valores que forman el codigo */ public void I n i c i a l i z a r T a b l e r o( int maxIntentos , int l a r g o C o d i g o) { // Creamos tablero , i n i c i a l i z a d o en -1 t a b l e r o J u e g o = new int [ m a x I n t e n t o s][ l a r g o C o d i g o]; for ( int i = 0; i < t a b l e r o J u e g o. length ; i ++) { for ( int j = 0; j < t a b l e r o J u e g o[ i ]. length ; j ++) { t a b l e r o J u e g o[ i ][ j ] = -1; } } // Creamos tablero de ayudas , i n i c i a l i z a d o en -1 t a b l e r o A y u d a s = new int [ m a x I n t e n t o s ][2]; for ( int i = 0; i < t a b l e r o J u e g o. length ; i ++) { for ( int j = 0; j < 2; j ++) { t a b l e r o A y u d a s[ i ][ j ] = -1; } } } /* * * Metodo que genera un codigo de forma a l e a t o r i a con todos los valores * distintos * @param l a r g o C o d i g o : numero de valores que forman el codigo * @param rangoMax : valor maximo para cada uno de los numeros que forman el codigo */ public void G e n e r a r C o d i g o( int largoCodigo , int rangoMax ) { // Creamos el arreglo codigo = new int [ l a r g o C o d i g o]; // G e n e r a m o s los valores al azar , buscando que no se repitan for ( int i = 0; i < codigo . length ; i ++) { boolean aceptado = false ; // Lo c o m p a r a m o s con los valores a n t e r i o r e s while (! aceptado ) { codigo [ i ] = A l e a t o r i o. entero (1 , rangoMax ); aceptado = true ; for ( int j = i - 1; j >= 0; j - -) { if ( codigo [ j ] == codigo [ i ]) { aceptado = false ; } } } } } /* * * Intenta adivinar el codigo * @param intento : un arreglo con el intento de adivinar el codigo * @return si gano o todavia no */ public boolean Adivinar ( int [] intento ) { // O b t e n e m o s intento del jugador y lo ponemos en el tablero

IIC1103 Cap tulo 6: Arreglos

61

for ( int i = 0; i < t a b l e r o J u e g o[ n u m I n t e n t o s]. length ; i ++) { t a b l e r o J u e g o[ n u m I n t e n t o s][ i ] = intento [ i ]; } // R e v i s a m o s el intento y armamos las ayudas t a b l e r o A y u d a s[ n u m I n t e n t o s][0] = 0; t a b l e r o A y u d a s[ n u m I n t e n t o s][1] = 0; for ( int i = 0; i < codigo . length ; i ++) { // R e v i s a m o s si esta el numero correcto en el lugar correcto if ( codigo [ i ] == t a b l e r o J u e g o[ n u m I n t e n t o s][ i ]) { t a b l e r o A y u d a s[ n u m I n t e n t o s ][1]++; // Le achunto al numero , y en // el lugar adecuado } else { // Si no esta en el lugar correcto , buscamos si al menos esta en // otro lugar for ( int j = 0; j < t a b l e r o J u e g o[ n u m I n t e n t o s]. length ; j ++) { if (( i != j ) && ( t a b l e r o J u e g o[ n u m I n t e n t o s][ i ] == codigo [ j ])) { t a b l e r o A y u d a s[ n u m I n t e n t o s ][0]++; // Le achunto al numero , pero no en el lugar adecuado } } } } // R e v i s a m o s si gano boolean gano = false ; if ( t a b l e r o A y u d a s[ n u m I n t e n t o s ][1] == codigo . length ) { gano = true ; } // A v a n z a m o s y r e t o r n a m o s n u m I n t e n t o s++; return gano ; } /* * Metodo p r i n c i p a l del juego * @param m a x I n t e n t o s : numero maximo de intentos * @param l a r g o C o d i g o : numero de valores que forman el codigo * @param rangoMax : valor maximo para cada uno de los numeros que forman el codigo */ public void I n i c i a r J u e g o( int maxIntentos , int largoCodigo , int rangoMax ) { I n i c i a l i z a r T a b l e r o( maxIntentos , l a r g o C o d i g o); G e n e r a r C o d i g o( largoCodigo , rangoMax ); // Ciclo p r i n c i p a l boolean salir = false ; while (! salir ) { // M o s t r a m o s tablero , o b t e n e m o s opcion y r e v i s a m o s int opcion = GUI . M o s t r a r E s t a d o J u g a d o r( tableroJuego , tableroAyudas , m a x I n t e n t o s - n u m I n t e n t o s); if ( opcion == 1) { // O b t e n e m o s c o o r d e n a d a s y marcamos int [] intento = GUI . O b t e n e r I n t e n t o( rangoMax , l a r g o C o d i g o); boolean gano = Adivinar ( intento ); // Revisa si gano o perdio , si ya marco todas if ( gano ) { Usuario . mensaje ( " A d i v i n a s t e! Ganaste el juego . " ); GUI . M o s t r a r C o d i g o( codigo ); return ; } else if ( n u m I n t e n t o s == t a b l e r o J u e g o. length ) { Usuario . mensaje ( " Se te acabaron los intentos ! Perdiste el juego . " ); GUI . M o s t r a r C o d i g o( codigo ); return ; } } else if ( opcion == 2) { GUI . M o s t r a r C o d i g o( codigo ); } else if ( opcion == 3) { salir = true ; } } } } import i i c 1 1 0 3 P a c k a g e .*; public class P r i n c i p a l { public static void main ( String [] args ) { // Crea el objeto del juego

IIC1103 Cap tulo 6: Arreglos

62

M a s t e r M i n d juego = new M a s t e r M i n d(); // Pedimos al usuario los datos c o r r e s p o n d i e n t e s int m a x I n t e n t o s = Usuario . entero ( " Ingrese el numero maximo de intentos : " ); int l a r g o C o d i g o = Usuario . entero ( " Ingrese el largo del codigo : " ); int maxRango = Usuario . entero ( " Ingrese el maximo para los valores del codigo : " ); // R e v i s a m o s que sea mayor o igual al largo while ( maxRango < l a r g o C o d i g o) { maxRango = Usuario . entero ( " Ingrese el maximo para los valores del codigo : " ); } // Comienza el juego juego . I n i c i a r J u e g o( maxIntentos , largoCodigo , maxRango ); } }

IIC1103 Cap tulo 6: Arreglos

63

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