SlideShare una empresa de Scribd logo
1 de 53
Descargar para leer sin conexión
Pontificia Universidad Cat´olica de Chile
Escuela de Ingenier´ıa
Departamento de Ciencia de la Computaci´on
IIC1103 — Introducci´on a la Programaci´on
Cap´ıtulo 5: Strings
Resumen te´orico
Los Strings son una secuencia de caracteres, incluyendo letras (may´usculas y min´usculas), signos, espacios,
caracteres especiales, etc. En palabras simples, los Strings sirven para guardar palabras, oraciones, etc. En
java los Strings son objetos, tipo String. Al momento de crearlos, la manera m´as sencilla es:
String hola = "Hello World";
Los Strings, al ser objetos, tambi´en pueden ser inicializados como tales, a trav´es del constructor:
String s = new String(); // String vacio
String s = new String("Hola"); // String "Hola"
M´etodos de la clase String
La clase String tiene una gran variedad de m´etodos ´utiles. La lista completa puede encontrarse en la documen-
taci´on oficial (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html). A continuaci´on explicamos
los m´etodos que m´as se utilizan en este curso.
int length()
Sencillamente, retorna el largo (la cantidad de caracteres) de un String.
String texto1 = "Hola";
String texto2 = "(/.,;>.)";
String texto3 = "";
String texto4 = " ";
int n = texto1.length(); // 4
int m = texto2.length(); // 8
int p = texto3.length(); // 0
int q = texto4.length(); // 1
char charAt(int index)
Retorna el caracter que se encuentra en la posici´on dada por index. Si index es mayor o igual que el largo del
String, el programa se caer´a al ejecutar, aunque Eclipse no le avisar´a al respecto (no es capaz de prever dicho
comportamiento), y al compilar tampoco habr´a errores. Por esta raz´on, cada vez que utilice este m´etodo
debe primero revisar el largo del String.
String texto = "¡Hola Juanito!";
char c1 = texto.charAt(0); // ’¡’
char c2 = texto.charAt(1); // ’H’
char c3 = texto.charAt(13); // ’!’
char c4 = texto.charAt(20); // error
char c5 = texto.charAt( texto.length() - 1 ); // ’!’
IIC1103 – Cap´ıtulo 5: Strings 1
Ejemplo de c´omo evitar errores:
String texto = Usuario.texto("Ingrese un texto:");
char c;
if(texto.length() > 20) {
c = texto.charAt(20);
//...
} else {
Usuario.mensaje("String");
}
boolean startsWith(String s)
Devuelve true si el String comienza con el String s entregado como par´ametro. La coincidencia debe ser
exacta (se distingue may´usculas de min´usculas, por ejemplo, y los caracteres con tilde no son iguales a los
que no lo llevan).
String texto = "¡Hola Juanito!";
boolean b1 = texto.startsWith("¡"); // true
boolean b2 = texto.startsWith("¡Hola ") // true
boolean b3 = texto.startsWith("¡hola Juanito!") // false
boolean b4 = texto.startsWith("¡Hola Juanito! ") // false
boolean b5 = texto.startsWith("¡Hola Juanito!") // true
boolean startsWith(String s, int k)
Como el m´etodo anterior, pero comienza a revisar desde el ´ındice (posici´on) k, sin importar lo que haya
antes. Si k == 0, entonces el m´etodo es equivalente al anterior.
String texto = "¡Hola Juanito!";
boolean b1 = texto.startsWith("Hola", 1); // true
boolean b2 = texto.startsWith(" Juanito!", 5); // true
boolean b3 = texto.startsWith("a", 7); // false
boolean b4 = texto.startsWith("¡", 20); // false
int indexOf(char c)
Devuelve un entero que indica la posici´on donde aparece por primera vez el caracter c. Si el caracter no
aparece en todo el String, devuelve -1.
String texto = "¡Hola Juanito!";
int n = texto.indexOf(’o’); // 2
int m = texto.indexOf(’ ’); // 5
int p = texto.indexOf(’¡’); // 0
int q = texto.indexOf(’z’); // -1
int indexOf(String s)
Similar al anterior, s´olo que devuelve la posici´on donde aparece por primera vez un determinado String.
String texto = "En la arboleda un arbolito";
int n = texto.indexOf("arbol"); // 6
int m = texto.indexOf("´arbol"); // -1
int p = texto.indexOf("boli"); // 20
int q = texto.indexOf("bol"); // 8
IIC1103 – Cap´ıtulo 5: Strings 2
int indexOf(char c, int fromIndex) y int indexOf(String s, int fromIndex)
Como el m´etodo indexOf(String s), pero comienza a buscar desde la posici´on fromIndex.
int lastIndexOf(char c), int lastIndexOf(String s), int lastIndexOf(char c, int fromIndex), int
lastIndexOf(String s, int fromIndex)
Como indexOf(char c), pero en vez de buscar la primera aparici´on del char c, busca la ´ultima. Retorna -1 si
no lo encuentra. Se definen de manera an´aloga a los anteriores:
boolean equals(String s)
Retorna true cuando ambos String son exactamente iguales. Esto quiere decir que el largo de ambos es el
mismo, y que en cada posici´on encontramos el mismo caracter.
String texto1 = "casa";
String texto2 = "caza";
String texto3 = "casi";
String texto4 = "casa";
String texto5 = "CaSa";
boolean b1 = texto1.equals(texto3); // false
boolean b2 = texto4.equals(texto1); // true
boolean b3 = texto3.equals(texto1); // false
boolean b4 = texto1.equals(texto5); // false
boolean equalsIgnoreCase(String s)
Retorna true cuando ambos String son iguales, sin importar may´usculas y min´usculas.
String texto1 = "casa";
String texto2 = "caza";
String texto3 = "casi";
String texto4 = "casa";
String texto5 = "CaSa";
boolean b1 = texto1.equalsIgnoreCase(texto3); // false
boolean b2 = texto4.equalsIgnoreCase(texto1); // true
boolean b3 = texto3.equalsIgnoreCase(texto1); // false
boolean b4 = texto1.equalsIgnoreCase(texto5); // true
int compareTo(String s)
Este m´etodo compara lexicogr´aficamente dos String. Parte en el primer par de caracteres hasta encontrar
un par de char distintos. Si encuentra dos caracteres distintos, retorna la diferencia entre ellos (recuerde que
char funciona como un n´umero entero). Si uno de los String comienza con el otro, retorna el n´umero de
caracteres adicionales que tiene. Si ambos String son iguales, retorna 0.
String texto = "radiograf´ıa";
int n = texto.compareTo("radio"); // 6
int m = texto.compareTo("radiolog´ıa"); // -5
int p = texto.compareTo("rabia"); // 2
int q = texto.compareTo("ralentizar"); // -8
int r = texto.compareTo("radiografia"); // 132
int s = texto.compareTo("radiograf´ıa"); // 0
IIC1103 – Cap´ıtulo 5: Strings 3
String substring(int inicio, int fin)
Retorna una parte del String: desde la posici´on inicio hasta la posici´on fin.
String texto = "desenfreno";
String subTexto = texto.substring(5, 10); // "freno"
String replaceAll(String aReemplazar , String reemplazo)
Reemplaza todas las ocurrencias de aReemplazar por reemplazo.
String t1 = "El auto volaba r´apido";
String t2 = t1.replaceAll("auto", "avi´on")); // "El avi´on volaba r´apido"
IIC1103 – Cap´ıtulo 5: Strings 4
Los Strings soportan todos los caracteres de la tabla ASCII:
Fuente de referencia:
http://users.physik.fu-berlin.de/~goerz/blog/wp-content/uploads/2008/09/ascii.gif
Para utilizarlos se puede “castear” un n´umero entero (la representaci´on decimal del caracter seg´un la tabla
ASCII) a un “char”.
char c = (char) 36; // signo pesos
Adem´as se pueden utilizar ciertos caracteres especiales, anteponiendo :
Descripci´on Representaci´on
Barra invertida 
Tabulaci´on horizontal t
Salto de L´ınea n
Comillas simples ’
Comillas dobles "
IIC1103 – Cap´ıtulo 5: Strings 5
Ejemplos
Problema 1: Varios
Enunciado
Escriba m´etodos en Java que:
Rote una palabra, por ejemplo “auto” queda “otua”.
Ocupe una palabra para crear un pal´ındrome, por ejemplo “auto” queda “autotua”.
Busque una palabra dentro de un texto y la marque con un “ ”, por ejemplo “auto” en “Habian muchos
autos” queda “Habian muchos autos”.
Cuente la cantidad de ocurrencias de una palabra en un texto, por ejemplo “hola” en “El gato decia
hola muchas veces al dia, hola”, retorna 2.
Criterios de soluci´on
Para rotar la palabra basta con crear un nuevo String (nueva variable) e ir concaten´andole las le-
tras de nuestro String original, pero recorriendo el original desde atr´as hacia adelante (for por su
largo/length).
Muy similar al anterior, se puede hacer de dos maneras. Se le puede concatenar el string obtenido con
el m´etodo anterior o se puede hacer de manera manual.
Para encontrar donde aparece la palabra es claro que hay que ocupar indexOf. Para agregar el “ ” la
mejor manera es guardar la posici´on donde est´a la palabra buscada y ocuparla para separar la oraci´on
en dos substrings, uno con todos los caracteres a la izquierda de la posici´on y otro a la derecha. Luego
concatenamos el subtring de la izquierda con un “ ” y el substring de la derecha.
Para contar la cantidad de veces que aparece la palabra ocupamos indexOf para ver si est´a, si la posici´on
es distinta de -1 sumamos uno a la cantidad de veces que encontramos la palabra. Es importante cambiar
la posici´on desde la que buscamos en nuestro String ya que, o si no, podemos contar infinitas veces la
misma palabra.
IIC1103 – Cap´ıtulo 5: Strings 6
Posible soluci´on
import iic1103Package.*;
public class Principal {
public static String palindromizar(String palindrome) {
// obtengo el largo de la palabra enviada
int largo = palindrome. length ();
// iteramos hasta el largo menos 2
for (int i = largo - 2; i >= 0; i--) {
// le agregamos la ultima letra
palindrome = palindrome + palindrome.charAt (i);
}
return palindrome; // retorno el palindrome
}
public static String darVuelta(String palabra ) {
// aqui guardamos el resultado
String palabraRotada = "";
// parto desde el final y termino en el principio
for (int i = palabra . length () - 1; i >= 0; i--) {
// le voy agregando los caracteres
palabraRotada = palabraRotada + palabra . charAt (i);
}
// retorno la palabra rotada
return palabraRotada;
}
public static int buscarCantidad(String palabra , String textoAUsar) {
// Contamos cuantas veces esta la palabra
int veces = 0;
int pos = 0;
while (pos != -1) {
// Buscamos string y contamos , buscamos desde pos+1 para no volver a
// leer la misma palabra
pos = textoAUsar. indexOf (palabra , pos + 1);
// si pos es distinta de -1 contamos una vez mas
if (pos != -1) {
veces ++;
}
}
return veces;
}
public static boolean buscarPalabra(String palabra , String textoAUsar) {
// Busca la palabra
int pos = textoAUsar. indexOf (palabra );
if (pos != -1) {
// Agregamos "_"
String textoAMostrar = textoAUsar. substring(0, pos) + "_"
+ textoAUsar. substring(pos);
Usuario .mensajeConsola( textoAMostrar);
return true;
} else {
Usuario .mensajeConsola("No fue encontrado el string " + palabra
+ " en el texto ");
return false;
}
}
public static void main(String [] args) {
String nombre = "auto";
Usuario .mensajeConsola( palindromizar(nombre ));
Usuario .mensajeConsola( darVuelta(nombre ));
buscarPalabra("hola", "El gato decia hola muchas veces al dia , hola");
}
}
IIC1103 – Cap´ıtulo 5: Strings 7
Problema 2: Clase String
Enunciado
Un desarrollador est´a construyendo la clase String de Java, pero a medio camino deja el tema botado y se va
del pa´ıs. Sin poder contactarlo, le piden a usted completar la clase, sabiendo que la representaci´on interna,
constructores y operadores ya existen, y se encuentran ya disponibles los siguientes m´etodos:
char charAt(int index) Retorna el caracter en la posici´on index.
int compareTo(String another) Compara dos strings lexicogr´aficamente.
int length() Retorna el largo del string.
Para poder arreglar este dilema, le piden a usted desarrollar los siguientes m´etodos (utilizando s´olo lo ya
construido):
String substring(int begin, int end) Retorna el substring que va desde la posici´on begin
a la posici´on end, inclusive. Devuelve null si existe
alg´un problema con los ´ındices recibidos.
String toUpperCase() Retorna un string equivalente al actual, pero con
todas las letras convertidas a may´usculas. Ignore
caracteres que no pertenezcan al alfabeto ingl´es.
static valueOf(int i) Retorna el string que representa al entero i.
int indexOf(String str, int from) Retorna el ´ındice en que se encuentra el string str
en el string actual, o -1 si es que no se encuentra
(o cualquier otro problema). S´olo encuentra str a
a partir del ´ındice from.
Criterios de soluci´on
M´etodo substring: Lo primero que debemos hacer es revisar que los par´ametros recibidos correspondan
a ´ındices v´alidos seg´un el largo del String. Si el inicio es menor que cero y el fin mayor que el largo del
String -1 entonces retornamos false. Si no, para obtener un substring, debemos implementar un ciclo
(for por ejemplo) que recorra el String completo, desde el inicio hasta el fin recibidos como par´ametros,
y vaya obteniendo cada char con el m´etodo charAt y lo vaya concatenando, formando as´ı el substring
a retornar.
M´etodo toUpperCase: Para cambiar las letras a may´uscula debemos implementar un ciclo que recorra
todo el String obteniendo cada uno de sus caracteres con el m´etodo charAt. Luego revisamos cada
caracter si es que est´a en min´uscula, para esto basta con comparar si se encuentra en el rango de ’a’
a ’z’ (recordando que los caracteres est´an ordenados en la tabla ASCII). Si est´a en min´uscula lo que
tenemos que hacer es al inicio de las may´usculas ’A’ sumarle la distancia del caracter en min´uscula al
inicio de las min´usculas ’a’. As´ı, tendremos el mismo caracter pero ahora en may´uscula.
M´etodo valueOf: Para pasar el valor entero a String tenemos que revisar primero si el n´umero es
negativo o positivo. Si el n´umero es negativo tenemos que agregar un gui´on ’-’ al String resultante.
Luego recorremos el n´umero y vamos obteniendo cada uno de sus d´ıgitos (dividiendo el n´umero por
10 y obteniendo el resto) y para cada d´ıgito obtenemos el char que corresponde y lo concatenamos al
String que representa el resultado de pasar el n´umero a String.
M´etodo indexOf: En este m´etodo lo que tenemos que hacer es recorrer todo el String, partiendo desde
el inicio ingresado por el usuario. Dentro del ciclo debemos revisar el String ingresado como par´ametro
(el buscado) para revisar cada uno de sus caracteres y compararlos con el String original. As´ı si todos
los caracteres coinciden devolvemos la posici´on donde encontramos el primer caracter que fue igual.
IIC1103 – Cap´ıtulo 5: Strings 8
Posible soluci´on
/**
* Retorna el substring que va desde la posicion begin a la posicion end ,
* inclusive. Devuelve null si existe algun problema con los indices
* recibido .
*/
public String substring(int begin , int end) {
if ( begin < 0 || end > length () - 1)
return null;
String res = "";
for (int i = begin; i <= end; i++)
res += charAt (i);
return res;
}
/**
* Retorna un string equivalente al actual , pero con todas las letras
* convertidas a mayuscula. Ignora caracteres que no pertenezcan al alfabeto
* ingles
*/
public String toUpperCase() {
String res = "";
for (int i = 0; i < length (); i++) {
char aux = charAt (i);
if (’a’ <= aux && aux <= ’z’)
res += (char) (aux + ’A’ - ’a’);
else
res += aux;
}
return res;
}
/**
* Retorna el string que representa al entero i.
*/
public static String valueOf (int i) {
if (i == 0)
return "0";
boolean negative = false;
if (i < 0) {
negative = true;
i = -i;
}
String res = "";
while (i > 0) {
res = " " + (char) (i % 10 + ’0’) + res;
i /= 10;
}
if ( negative )
res = "-" + res;
return res;
}
/**
* Retorna el indice en que se encuentra el string str en el string actual ,
* o -1 si es que no se encuentra (o cualquier otro problema ). Solo
* encuentra str a a partir del indice from.
*/
public int indexOf (String str , int from) {
for (int i = from; i < length (); i++) {
for (int j = 0; (i + j < length ())
&& charAt (i + j) == str.charAt (j); j++) {
if (j == str.length () - 1)
return i;
}
}
return -1;
}
IIC1103 – Cap´ıtulo 5: Strings 9
Problema 3: Iniciando un Juego
Enunciado
Debemos crear un algoritmo que permita inicializar un juego. Para ello debe pedir un texto al usuario en
que se indiquen los datos necesarios. La primera palabra de este texto representar´a el modo en el cual se va a
jugar, pudiendo ser MULTI, PC o DEMO. Luego viene un signo punto y coma (;) seguido por los nombres de
los jugadores que intervendr´an en el juego separados entre ellos por un gui´on (-). En caso de ser en modo PC
solamente viene el nombre de un jugador, en cambio si es modo MULTI pueden venir entre 2 y 4 nombres.
Los siguientes son un ejemplo del texto que se ingresa:
MULTI;Marcos-Karen-Marcelo-Rosa
PC;Marcos
Para el primer texto su programa debiera iniciarse en modo Multi usuario para cuatro jugadores, con los
nombres ah´ı descritos.
En caso de ingresarse el segundo texto, su programa debiera inicializarse en modo versus PC, con un ´unico
usuario llamado Marcos.
Criterios de soluci´on
Se nos pide reconocer un texto ingresado por el usuario. Como datos nos dan que los separadores son “;”
y “-”, para ello nuestro programa tiene que ser capaz de buscar el car´acter “;” (charAt()), en una primera
instancia para poder realizar la separaci´on. Luego se nos pide verificar que la primera parte corresponda
a “MULTI”, “PC” o “DEMO” (validaci´on con equals). Con la segunda parte de esta divisi´on hacemos lo
mismo que al principio y separamos por “-”, verificando que la cantidad de jugadores ingresados corresponda
a la se˜nalada seg´un el enunciado.
Posible soluci´on
import iic1103Package.*;
public class Principal {
public static void main(String [] args) {
while (true) {
String x = Usuario .texto ("Ingrese el mensaje a validar ");
if (Validador(x))
break ;
}
}
// Metodo que valida el texto que es ingresado
static boolean Validador(String validar ) {
int donde = validar . indexOf (";"); // buscamos el separador ";"
if ( donde == -1 && ! validar .equalsIgnoreCase("DEMO")) {
Usuario .mensaje ("No es un formato valido ");
return false;
} else if (validar . equalsIgnoreCase("DEMO")) {
// Notamos el tipo DEMO
Usuario .mensaje ("Tipo de juego: DEMO");
return true;
}
String parte1 = validar . substring(0, donde );
String parte2 = validar . substring(donde + 1);
String mensaje = "";
// Buscamos la contidad de jugadores
int jugadores = cantidad_jugadores(parte2 );
if ( jugadores > 4) {
// No pueden existir mas de 4 jugadores:
Usuario .mensaje ("No es un formato valido : Ingreso mas de 4 jugadores");
return false;
}
IIC1103 – Cap´ıtulo 5: Strings 10
if ( parte1 . equalsIgnoreCase("PC")) {
if (jugadores == 0) {
// El tipo PC requiere minimo 1 jugador
Usuario .mensaje ("No es un formato valido : No especifico jugadores para Pc");
return false;
}
mensaje = "Tipo de juego: PC" + ’n’ + jugadores(parte2 );
} else if (parte1 . equalsIgnoreCase("MULTI")) {
if (jugadores < 2) {
// El tipo MULTI requiere minimo 2 jugadores
Usuario .mensaje ("No es un formato valido : no ingreso suficientes jugadores para el tipo Multi");
return false;
}
mensaje = "Tipo de juego: MULTI" + ’n’ + jugadores(parte2 );
} else {
Usuario .mensaje ("No es un formato valido ");
return false;
}
Usuario .mensaje (mensaje );
return true;
}
// Metodo que Determina la cantidad de jugadores existentes
static int cantidad_jugadores(String jugadores) {
if ( jugadores.length () == 0) {
return 0;
}
int cantidad = 1;
for (int i = 0; i < jugadores.length (); i++) {
if (jugadores.charAt (i) == ’-’) {
cantidad ++;
}
}
return cantidad ;
}
// Metodo que retorna El mensaje correspondiente de los jugadores
static String jugadores(String parte2 ) {
String mensaje = "Jugador 1: ";
int y = 1;
for (int k = 0; k < parte2 .length (); k++) {
if (parte2 .charAt (k) == ’-’) {
// Encontro un ’-’... asi que se salta al siguiente jugador
y++;
mensaje += "nJugador " + y + ": ";
} else {
mensaje += parte2 . charAt (k);
}
}
return mensaje ;
}
}
IIC1103 – Cap´ıtulo 5: Strings 11
Problema 4: Double
Enunciado
Haga un c´odigo que permita determinar si un texto ingresado es un double, independiente que el n´umero este
separado con: ’.’ o ’,’. De ´esta forma podemos usar seguros el m´etodo Double.ParseDouble(String str);.
Criterios de soluci´on
Observamos que ´esta es una validaci´on simple, s´olo debemos verificar que los caracteres sean n´umeros, signo
negativo, o separadores v´alidos, adem´as de que s´olo exista un separador.
Adicionalmente podemos hacer el m´etodo que transforme las comas en puntos, para que Java pueda manejar
el n´umero.
Posible soluci´on
import iic1103Package.*;
public class Principal {
public static void main(String [] args) {
while (true) {
String x = Usuario .texto ("Ingrese el decimal a validar ");
if (esDouble (x)) {
x = remplazar(x);
double numero = Double .parseDouble(x);
Usuario .mensaje ("El numero ingresado es: " + numero );
break ;
}
}
}
// Metodo que valida si un numero es decimal
static boolean esDouble (String aComprobar) {
if ( aComprobar.length () == 0) {
// Si es vacio no sera un double
return false;
}
int comas = 0;
if (!(48 <= (int) aComprobar.charAt (0) && (int) aComprobar.charAt (0) <= 57)
&& !(( int) aComprobar.charAt (0) == 44 || (int) aComprobar
.charAt (0) == 46) && (int) aComprobar.charAt (0) != 45) {
return false;
// Si no es un numero , ni un separador ni un signo
// ’-’... no es un double
}
for (int i = 1; i < aComprobar.length (); i++) {
boolean esnumero = 48 <= (int) aComprobar. charAt (i)
&& (int) aComprobar.charAt (i) <= 57;
boolean escoma = (int) aComprobar.charAt (i) == 44
|| (int) aComprobar.charAt (i) == 46;
if (! esnumero && !escoma ) {
return false;
} else if (aComprobar. charAt (i) == 44 || aComprobar.charAt (i) == 46) {
comas ++;
if (comas > 1)
return false;
}
}
Usuario .mensaje ("Es un double ");
return true;
}
// Metodo que reemplaza la primera ’,’ por ’.’
static String remplazar(String s) {
int donde = s.indexOf (",");
if(donde != -1) {
return (s.substring(0, donde) + ’.’ + s. substring(donde + 1));
}else{
return s;
}
}
}
IIC1103 – Cap´ıtulo 5: Strings 12
Problema 5: Operaciones
Enunciado
Realice un m´etodo que reciba un String con una operaci´on b´asica (+, −, ∗, /) y devuelve el resultado de
esa operaci´on. Por ejemplo si recibe 4,5 + 35 debe devolver 39,5. Para esto puede ocupar s´olo los siguientes
m´etodos de la clase String:
charAt, length
Criterios de soluci´on
Lo primero que debemos hacer es identificar cu´al es la operaci´on que se encuentra en el String. Para esto
utilizamos un ciclo (un for por ejemplo), para recorrer todo el String e ir obteniendo cada uno de los
caracteres con el m´etodo charAt. Cada caracter lo comparamos con una de las posibles operaciones. Al
encontrar la operaci´on guardamos el caracter y tambi´en la posici´on donde la encontramos para luego obtener
los n´umeros que vienen en el String.
Para recuperar los n´umeros del String, como s´olo podemos utilizar el m´etodo charAt, lo que hacemos son dos
ciclos, uno que recorra la primera parte del string obteniendo cada uno de los caracteres y concaten´andolos
en un nuevo String que represente el primer n´umero, y el segundo ciclo que haga lo mismo pero con la
segunda parte del String.
Luego transformamos los Strings que representan a los n´umeros en variables de tipo double y revisando la
operaci´on encontrada retornamos el resultado de la operaci´on.
Posible soluci´on
public double Operacion(String op) {
// Debemos identificar cual es la operacion que se encuentra en el String
char opDada = 0;
int posOp = 0;
for (int i = 0; i < op. length (); i++) {
if (op.charAt (i) == ’+’ || op.charAt (i) == ’-’
|| op.charAt (i) == ’*’ || op.charAt (i) == ’/’) {
opDada = op.charAt (i);
posOp = i;
break ;
}
}
// Ahora debemos identificar los valores involucrados
double valor1 = 0, valor2 = 0;
String aux = "";
for (int i = 0; i < posOp ; i++) {
aux += op.charAt (i);
}
valor1 = Double . parseDouble(aux);
aux = "";
for (int i = posOp + 1; i < op.length (); i++) {
aux += op.charAt (i);
}
valor2 = Double . parseDouble(aux);
if ( opDada == ’+’) {
return valor1 + valor2 ;
} else if (opDada == ’-’) {
return valor1 - valor2 ;
} else if (opDada == ’*’) {
return valor1 * valor2 ;
} else {
return valor1 / valor2 ;
}
}
IIC1103 – Cap´ıtulo 5: Strings 13
Problema 6: Palabra Abecedaria
Enunciado
Una palabra se dice abecedaria si las letras que la forman se encuentran en orden alfab´etico si son le´ıdas de
izquierda a derecha. Por ejemplo, las siguientes palabras cumplen con ser abecedarias:
Amor, filo, chintz, luz, dinos.
Escriba un m´etodo que permita determinar si una palabra es abecedaria. El m´etodo debe recibir un string
como par´ametro y retornar verdadero en caso que la palabra sea abecedaria, y falso en caso contrario. Para
esto puede ocupar s´olo los siguientes m´etodos de la clase String:
charAt, length, equals, compareTo
Criterios de soluci´on
Para revisar si la palabra es abecedaria tenemos que ir revisando cada uno de los caracteres y ver que ninguno
sea mayor (lexicogr´aficamente) que el siguiente. Para eso lo mejor es utilizar un ciclo, un for por ejemplo,
para recorrer la palabra entera, caracter por caracter. Utilizando el m´etodo charAt obtenemos el caracter
actual y el siguiente y comparamos si el actual es mayor que el siguiente. Si esto ocurre retornamos false, de
lo contrario seguimos revisando el resto de la palabra.
Adem´as de esto tenemos que considerar que pueden haber caracteres en may´uscula, los cuales para que lo
anterior funcione debemos pasarlos a min´uscula. Para esto simplemente le restamos el inicio de las letras
may´usculas (’A’) y le sumamos el inicio de las letras min´usculas (’a’).
Posible soluci´on
public class Palabra {
public boolean abecedaria(String palabra ) {
for (int i = 0; i < palabra .length () - 1; i++) {
char primeraLetra = palabra .charAt (i);
char segundaLetra = palabra .charAt (i + 1);
if (primeraLetra >= ’A’ && primeraLetra <= ’Z’)
primeraLetra = (char) (( int) primeraLetra - (int) ’A’ + (int) ’a’);
if (segundaLetra >= ’A’ && segundaLetra <= ’Z’)
segundaLetra = (char) (( int) segundaLetra - (int) ’A’ + (int) ’a’);
if (primeraLetra > segundaLetra)
return false;
}
return true;
}
}
IIC1103 – Cap´ıtulo 5: Strings 14
Problema 7: Combinaci´on
Enunciado
Implemente una clase llamada Combinacion, la cual recibe dos String en el constructor. Su clase debe tener
un m´etodo que reciba un char y retorne la cantidad de apariciones de ese char en ambos textos. Un m´etodo
que retorne un String formado por la intercalaci´on de las letras que forman ambos textos. Otro m´etodo que
retorne el resultado de la comparaci´on entre dos substrings de los textos, recibiendo como par´ametros los
´ındices iniciales y finales para cada uno de ellos. Finalmente un m´etodo que permita reemplazar un cierto
char por otro en ambos textos.
Para esto puede ocupar s´olo los siguientes m´etodos de la clase String:
charAt, length, equals, compareTo
Criterios de soluci´on
Lo primero que debemos hacer es declarar la clase Combinacion con dos atributos de tipo String. Luego
debemos crear el constructor, el cual reciba dos Strings como par´ametros y los asigne a los atributos
correspondientes.
Para el m´etodo encargado de contar las apariciones de un char entregado como par´ametro, lo que
tenemos que hacer es un ciclo (for por ejemplo) que recorra ambos Strings y vaya comparando cada
uno de sus caracteres, utilizando el m´etodo charAt e ir contando en una variable cuantas veces el
caracter es igual al recibido como par´ametro.
Para el m´etodo que intercale ambos Strings lo que tenemos que hacer es nuevamente implementar un
ciclo que vaya recorriendo cada String y obteniendo uno a uno sus caracteres con el m´etodo charAt.
As´ı se concatena un caracter del primer String seguido de un caracter del segundo. En este m´etodo
tenemos que revisar siempre que el String a´un no se acabe ya que puede ocurrir que uno sea m´as largo
que el otro, en tal caso simplemente intercalamos hasta que se termine el menor y luego concatenamos
el resto del mayor.
Para el m´etodo que compara dos substrings de los textos debemos primero obtener los substrings seg´un
los datos de inicio y fin recibidos como par´ametros. Para esto implementamos ciclos que recorran los
strings desde el inicio hasta el fin recibidos como par´ametros y vayan formando los dos substrings,
concatenando los caracteres que se obtienen utilizando el m´etodo charAt. Luego utilizando el m´etodo
equals o compareTo, revisamos si son iguales, y retornamos true o false seg´un corresponda.
Para el m´etodo que reemplace un char por otro lo que podemos hacer es implementar un ciclo que
recorra ambos textos y que vaya obteniendo, con el m´etodo charAt, cada uno de los caracteres. Revi-
samos el caracter comparando si es igual al que se quiere reemplazar. Si es as´ı, concatenamos el nuevo
char, si no lo es, concatenamos el char original, formando as´ı el texto con los caracteres reemplazados.
IIC1103 – Cap´ıtulo 5: Strings 15
Posible soluci´on
public class Combinacion {
private String texto1 ;
private String texto2 ;
public Combinacion(String t1 , String t2) {
texto1 = t1;
texto2 = t2;
}
public int Apariciones(char c) {
String t = texto1 + texto2 ;
int apariciones = 0;
for (int i = 0; i < t. length (); i++) {
if (t.charAt (i) == c) {
apariciones++;
}
}
return apariciones;
}
public String Intercalacion() {
String res = "";
for (int i = 0; i < texto1 .length () || i < texto2 .length (); i++) {
if (i < texto1 .length ()) {
res += texto1 .charAt (i);
}
if (i < texto2 .length ()) {
res += texto2 .charAt (i);
}
}
return res;
}
public boolean Comparar (int i1 , int f1 , int i2 , int f2) {
// Obtenemos ambos substrings
String t1 = "";
String t2 = "";
for (int i = i1; i <= f1; i++) {
t1 += texto1 .charAt (i);
}
for (int i = i2; i <= f2; i++) {
t2 += texto2 .charAt (i);
}
return t1.equals (t2);
}
public void Reemplazar(char charOriginal , char charReemplazo) {
String aux = "";
for (int i = 0; i < texto1 .length (); i++) {
if (texto1 .charAt (i) == charOriginal) {
aux += charReemplazo;
} else {
aux += texto1 .charAt (i);
}
}
texto1 = aux;
aux = "";
for (int i = 0; i < texto2 .length (); i++) {
if (texto2 .charAt (i) == charOriginal) {
aux += charReemplazo;
} else {
aux += texto2 .charAt (i);
}
}
texto2 = aux;
}
}
IIC1103 – Cap´ıtulo 5: Strings 16
Problema 8: C´odigo Simple
Enunciado
Haga un programa que dado un mensaje y un n´umero codifique el mensaje, moviendo las letras un n´umero
de posiciones igual al n´umero ingresado, en la tabla ASCII. Por simplicidad puede transformar el mensaje a
min´usculas. Adem´as escriba en el main una prueba del funcionamiento del programa.
Criterios de soluci´on
Seg´un el enunciado, primero debemos pedir al usuario el mensaje a codificar y un n´umero (lo llamaremos base
del c´odigo). Dados estos n´umeros debemos obtener el valor de cada letra (s´olo las letras) en la tabla ASCII,
y sumarle la base. Luego imprimiremos el mensaje, para mostrar el mensaje codificado. Para decodificar el
mensaje el procedimiento es inverso, debemos restar la base, pero considerando que cambiaron los extremos
en que los caracteres corresponden a letras (se suma la base a cada extremo). Adem´as debemos decodificar
el mensaje con una base distinta, para mostrar que se requiere de ´esta para poder realizar la operaci´on.
Posible soluci´on
import iic1103Package.*;
public class Principal {
public static void main(String [] args) {
String mensaje = Usuario . texto("Ingrese el mensaje que desea codificar.");
int base = Usuario .entero (" Ingrese la base del codigo ");
String codificado = codificar(mensaje , base);
Usuario .mensaje (" Codificado:n" + codificado);
Usuario .mensaje (" Decodificado Base 10:n" + decodificar(codificado , 10));
Usuario .mensaje (" Decodificado Base " + base + ":n"
+ decodificar(codificado , base ));
}
public static String codificar(String mensaje , int base) {
String resultado = "";
mensaje = mensaje . toLowerCase();
for (int i = 0; i < mensaje .length (); i++) {
if (mensaje .charAt (i) >= 97 && mensaje . charAt (i) <= 122) {
resultado += (char) ( mensaje .charAt (i) + base );
} else {
resultado += (char) mensaje .charAt (i);
}
}
return resultado;
}
public static String decodificar(String mensaje , int base) {
String resultado = "";
mensaje = mensaje . toLowerCase();
for (int i = 0; i < mensaje .length (); i++) {
if (mensaje .charAt (i) >= 97 + base
&& mensaje .charAt (i) <= 122 + base) {
resultado += (char) ( mensaje .charAt (i) - base );
} else {
resultado += (char) mensaje .charAt (i);
}
}
return resultado;
}
}
IIC1103 – Cap´ıtulo 5: Strings 17
Problema 9: Ahorcado
Enunciado
Realice un programa en Java para jugar “Al ahorcado”. Recuerde que este juego consiste en tratar de adivinar
una palabra, letra por letra, en una cantidad preestablecida de intentos. Para este problema suponga que la
palabra (oraci´on 1
) a adivinar es “hola mundo”, aceptando a lo m´as 3 intentos fallidos por parte del usuario.
Solicite a trav´es de una ventana al usuario que ingrese las letras, y muestre en consola la palabra con las
letras que lleva descubiertas.
Ejemplo: si el mensaje es “hola mundo”, y el usuario a ingreso “o”, “a”, “z”, debe mostrar en consola
_o_a ____o .
Por simplicidad puede suponer que tanto el mensaje secreto, como las letras ingresadas por el usuario, son
en min´uscula.
Criterios de soluci´on
El enunciado nos da pocas restricciones, salvo el mensaje y la cantidad de intentos. Pero sabemos que
debemos validar que el usuario ingrese s´olo una letra, comparar si corresponde a alguna(s) de la palabra
secreta, y de ser as´ı cambiarla. Repetir esto mientras no haya ganado (descifrado la palabra completa) o
perdido (alcanzado el m´aximo de errores permitidos).
Posible soluci´on
import iic1103Package.*;
public class PrincipalAhorcado {
/** * Programa para jugar el juego del Ahorcado */
public static void main(String [] args) {
String palabraClave = "hola mundo"; // palabra clave establecida
int intentos = 3; // cantidad de intentos establecidos
// creamos un objetos de la clase Ahorcado
Ahorcado a1 = new Ahorcado (palabraClave , intentos );
// mostramos el mensaje inicial
Usuario .mensaje (" Bienvenido! "
+ "nIntente adivinar la palabra secreta . Tiene " + intentos
+ " intentos ");
// ciclo del juego (mientras pueda seguir jugando )
while (a1.seguirJugando()) {
// mostrar lo que lleva
Usuario .mensaje ("Hasta ahora lleva: " + a1. getPalabraActual());
// guardaremos la letra que ingrese el usuario
String palabra = "";
// verificamos que sea solo una letra
while (palabra .length () != 1) {
palabra = Usuario .texto ("Ingrese la letra que quiere descubrir: ");
}
// tomamos el primer caracter del string
char c = palabra .charAt (0);
// preguntar si esta en la palabra secreta
a1. preguntarLetra(c);
}
// fuera del while (se acabo el juego)
// vemos si gano
if (a1.gano ()) {
// mostramos el mensaje de felicitacion
Usuario .mensaje (" Felicitaciones! Ha descubierto la palabra secreta ");
} else {
// perdio , mostramos el mensaje avisando
Usuario .mensaje ("Ha perdido ." + "n La palabra era: "
+ a1. getPalabraClave());
}
}
}
1si ingresa una oraci´on, los espacios no se deben ocultar, es decir, colocando el “ ”
IIC1103 – Cap´ıtulo 5: Strings 18
public class Ahorcado {
// [ ATRIBUTOS]
String palabraClave; // palabra clave del juego
String palabraActual; // palabra que lleva el usuario
int intentosFallidos; // cantidad de intentos fallidos
int intentosMaximo; // cantidad de intentos maximos por fallar
// [METODOS ]
// Constructor de la clase
public Ahorcado (String palabraClave , int intentosMaximo) {
this. palabraClave = palabraClave;
this. intentosFallidos = 0;
this. intentosMaximo = intentosMaximo;
this. palabraActual = ocultarPalabra( palabraClave);
}
// getters
public int getIntentosActual() {
return intentosFallidos;
}
public String getPalabraActual() {
return palabraActual;
}
public String getPalabraClave() {
return palabraClave;
}
// Otros ...
// metodo que determina si la letra esta en la palabra clave
public void preguntarLetra(char c) {
if (this.palabraClave. contains (c + "")) {
descubrirLetra(c);
} else {
this. intentosFallidos++;
}
}
// metodo que cambia cada "_" por la letra que corresponde
public void descubrirLetra(char c) {
String aux = "";
for (int i = 0; i < this. palabraClave.length (); i++) {
if (this.palabraClave. charAt (i) == c) {
aux += this. palabraClave.charAt (i);
} else {
aux += this. palabraActual.charAt (i);
}
}
this. palabraActual = aux;
}
// esconde la palabra clave , cambiando cada caracter por "_"
public String ocultarPalabra(String m) {
String s = "";
for (int i = 0; i < m. length (); i++) {
if (m.charAt (i) == ’ ’) {
s += " ";
} else {
s += "_";
}
}
return s;
}
// determina si se puede seguir jugando (no ha ganado ni perdido )
public boolean seguirJugando() {
if (this.intentosFallidos < this. intentosMaximo && !gano ()) {
return true;
} else {
return false;
}
}
// determina si gano
public boolean gano() {
return this.palabraClave. equals (this. palabraActual);
}
}
IIC1103 – Cap´ıtulo 5: Strings 19
Problema 10: Jerigonza
Enunciado
La jerigonza, jerigonzo o jerigoncio es una variante l´udica del habla2
. En jerigonza “escondido” se dice
epescopondipidopo.
Adem´as del entretenimiento, tambi´en puede usarse como un modo de codificar el mensaje de forma que otras
personas cercanas a los hablantes no acostumbrados a esta forma de hablar no consigan entender lo que los
hablantes dicen.
Se le pide realizar un programa que codifique, y decodifique, mensajes escritos en este dialecto. Para ello, se
sabe que despu´es de cada vocal se agrega el sonido “p” y se repite la vocal 3
. “Carlos” genera “Caparlopos”.
Por simplicidad, puede asumir que el usuario ingresar´a texto sin tildes Ejemplo: (conversaci´on)
Hopolapa, ¿copomopo epestapas? (Hola, ¿como estas?)
Yopo epestopoypi bipiepen, ¿ypi tupu? (Yo estoy bien, ¿y tu?)
Tapambiepen, grapacipiapas. (Tambien, gracias.)
Epestapamopos hapablapandopo epen jeperipigoponzapa (Estamos hablando en jerigonza)
Epesopo yapa lopo sapabipiapa (Eso ya lo sabia)
Criterios de soluci´on
Es realmente f´acil. Debemos revisar cada letra: si es una vocal se repite como dice el enunciado, y cualquier
otro caracter se deja igual, salvo la “y” que se considerar´a como vocal, siempre y cuando lo que siga no
sea una vocal (en este caso, hay que cuidar que no pasemos el largo del string).
2http://es.wikipedia.org/wiki/Jerigonza
3la letra “y” tambi´en ser´a considerada como vocal cuando corresponda, esto es, cuando no anteceda a alguna vocal
IIC1103 – Cap´ıtulo 5: Strings 20
Posible soluci´on
import iic1103Package.*;
public class Jerigonza {
/**
* Programa que escribe el texto ingresado por el usuario como Jerigonza.
* (se asume que no ingresa ningun tipo de tilde)
*/
public static void main(String [] args) {
String texto = Usuario .texto ("Ingrese el texto a Jerigonzar");
String cambiado = cambiar (texto );
Usuario .mensaje (cambiado );
}
private static String cambiar (String texto) {
String aux = "";
for (int i = 0; i < texto .length (); i++) {
if (texto.charAt (i) == ’a’) {
aux += "apa";
} else if (texto.charAt (i) == ’A’) {
aux += "Apa";
} else if (texto.charAt (i) == ’e’) {
aux += "epe";
} else if (texto.charAt (i) == ’E’) {
aux += "Epe";
} else if (texto.charAt (i) == ’i’) {
aux += "ipi";
} else if (texto.charAt (i) == ’I’) {
aux += "Ipi";
} else if (texto.charAt (i) == ’o’) {
aux += "opo";
} else if (texto.charAt (i) == ’O’) {
aux += "Opo";
} else if (texto.charAt (i) == ’u’) {
aux += "upu";
} else if (texto.charAt (i) == ’U’) {
aux += "Upu";
} else if (texto.charAt (i) == ’y’
&& ((i < texto. length () - 1) && texto. charAt (i + 1) != ’a’
&& texto.charAt (i + 1) != ’A’
&& texto.charAt (i + 1) != ’e’
&& texto.charAt (i + 1) != ’E’
&& texto.charAt (i + 1) != ’i’
&& texto.charAt (i + 1) != ’I’
&& texto.charAt (i + 1) != ’o’
&& texto.charAt (i + 1) != ’O’
&& texto.charAt (i + 1) != ’u’ && texto
.charAt (i + 1) != ’U’)) {
aux += "ypi";
} else if (texto.charAt (i) == ’Y’
&& ((i < texto. length () - 1) && texto. charAt (i + 1) != ’a’
&& texto.charAt (i + 1) != ’A’
&& texto.charAt (i + 1) != ’e’
&& texto.charAt (i + 1) != ’E’
&& texto.charAt (i + 1) != ’i’
&& texto.charAt (i + 1) != ’I’
&& texto.charAt (i + 1) != ’o’
&& texto.charAt (i + 1) != ’O’
&& texto.charAt (i + 1) != ’u’ && texto
.charAt (i + 1) != ’U’)) {
aux += "Ypi";
} else {
aux += texto.charAt (i);
}
}
return aux;
}
}
IIC1103 – Cap´ıtulo 5: Strings 21
Problema 11: Cifrado ROT13
Enunciado
Implemente una clase para encriptar/desencriptar mensajes utilizando el mecanismo de cifrado ROT13.
La clase debe contener por lo menos dos m´etodos:
public static String cifrar(String msg);
Encripta un mensaje en ROT13.
public static String descifrar(String msg);
Desencripta un mensaje en ROT13.
Descripci´on de ROT13 (http://es.wikipedia.org/wiki/Rot13/):
“ROT13 (“rotar 13 posiciones”) es un sencillo cifrado C´esar utilizado para ocultar un texto sustituyendo cada
letra por la letra que est´a trece posiciones por delante en el alfabeto. A se convierte en N, B se convierte en
O y as´ı hasta la M, que se convierte en Z. Luego la secuencia se invierte: N se convierte en A, O se convierte
en B y as´ı hasta la Z, que se convierte en M. Este algoritmo se utiliza en foros de Internet como medio para
ocultar de miradas casuales el final de un chiste, la soluci´on a un acertijo, un spoiler de una pel´ıcula o una
historia, o alg´un texto ofensivo. ROT13 se ha descrito como el “equivalente en Usenet de una revista que
imprime bocabajo la respuesta a un pasatiempo”.
El nombre “ROT13” se origin´o en Usenet a principios de los 80, y el m´etodo se ha convertido en un
est´andar de facto. El ROT13 no proporciona seguridad criptogr´afica real y no se usa para tales fines; de
hecho, a menudo se usa como ejemplo can´onico de cifrado d´ebil. Otra caracter´ıstica de este cifrado es que
es sim´etrico; esto es, para deshacer el ROT13, se aplica el mismo algoritmo, de manera que para cifrar y
descifrar se puede utilizar el mismo c´odigo.”
Criterios de soluci´on
Primero debemos tener en cuenta que este mecanismo s´olo toma en consideraci´on las 26 letras del abecedario,
sin considerar la ˜n. Luego, debemos sumar 13 posiciones a cada car´acter; si se ”pasa”de la z, volvemos a la
a. Como sabemos que lo char se pueden operar como si fueran enteros, basta con sumar 13 a cada char del
String.
Un punto muy importante es darse cuenta de que el mecanismo para descifrar es exactamente el mismo que
para cifrar, por lo tanto no hace falta replicar el c´odigo sino que simplemente el m´etodo descifrar(..) har´a un
llamado al m´etodo cifrar(..).
IIC1103 – Cap´ıtulo 5: Strings 22
Posible soluci´on
public class Cifrado {
// Declaro un metodo con nombre "cifrar "; retorna una variable de tipo
// String y recibe como argumento otro String .
public static String cifrar (String msg) {
// Creo una variable de tipo String y la inicializo con un String vacio .
String msgRot13 = "";
for (int i = 0; i < msg. length (); ++i) {
// Creo una variable de tipo char y almaceno el caracter que se
// encuentra en la posicion i del String msg.
char x = msg.charAt (i);
// A continuacion utilizare un "truco" para comparar caracteres
// utilizando su valor en la tabla ASCII.
// Noten que para escribir un caracter uso comillas simples en vez
// de comillas dobles , ya que las comillas dobles sirve para
// declarar variables de tipo String .
// Si el caracter es mayor o igual que ’A’ (en la tabla ASCII) y
// menor o igual que ’Z’
// (esto quiere decir: "si el caracter es una letra mayuscula")
if (x >= ’A’ && x <= ’Z ’) {
// Si me paso de Z, entonces le resto 13 al caracter .
if (x + 13 > ’Z’) {
x -= 13;
} else {
// Sino le sumo 13.
x += 13;
}
// Si el caracter es una letra minuscula , entonces ...
} else if (x >= ’a’ && x <= ’z’) {
// Si me paso de Z, entonces le resto 13 al caracter .
if (x + 13 > ’z’) {
x -= 13;
} else {
// Sino le sumo 13.
x += 13;
}
}
// Agrego x al resultado.
msgRot13 += x;
}
// Retorno el String cifrado .
return msgRot13 ;
}
// En ROT13 el cifrado y descifrado se realiza con la misma funcion , por lo
// tanto en el
// metodo descifrar simplemten llamo al metodo cifrar y retorno su valor .
public static String descifrar(String msg) {
return cifrar (msg);
}
}
IIC1103 – Cap´ıtulo 5: Strings 23
Problema 12: Codificaci´on
Enunciado
El algoritmo de codificaci´on del capit´an Crunch codifica un mensaje de texto tomando cada una de sus letras
y sum´andole 13. Por ejemplo, se convierte la letra ’a’ en ’ n ’ y la letra ’ b ’ en ’ o’. Las letras que se obtienen
forman una anillo al final, por lo que al codificar la letra ’z’ ´esta se convierte en ’m’. El procedimiento general
para codificar entonces, corresponde a sumar 13 a cada una de las letras, y para decodificar restar 13 a cada
letra. El m´etodo del capit´an Crunch se puede generalizar, de manera que, en lugar de agregar 13 a las letras,
se agregue un n´umero cualquiera.
Usted deber´a implementar la clase Codificador la cual permite codificar y decodificar mensajes usando el
algoritmo antes descrito. Puede suponer que el mensaje s´olo contiene letras min´usculas del alfabeto ingl´es
(i.e. sin ’ch’, ’ll’, ni ’˜n’). En detalle, su c´odigo deber´a cumplir con lo siguiente:
Su clase debe proveer de un m´etodo constructor que reciba como par´ametro la cantidad que se debe
sumar o restar a cada una de letras para codificar o decodificar un mensaje. El constructor debe verificar
que el valor recibido sea un entero mayor o igual que 0, y menor o igual que 26. El constructor adem´as
debe ser capaz de establecer si fue creado en forma exitosa para que cuando el objeto sea utilizado
para codificar o decodificar, se pueda determinar si la operaci´on se puede ejecutar o no.
Escriba un m´etodo que permita codificar y decodificar un mensaje. El m´etodo recibe como par´ametro
el mensaje y un boolean que indica si se desea codificar (true) o decodificar (false). El m´etodo retorna
un String con el mensaje codificado o decodificado seg´un sea el caso. En caso que el objeto codificador
no haya sido inicializado en forma exitosa retorna el mensaje ”#ERROR#”.
Para esto puede ocupar s´olo los siguientes m´etodos de la clase String:
charAt, length, equals, compareTo
Criterios de soluci´on
Lo primero que debemos hacer, como nos indica el enunciado, es implementar el constructor de la clase. ´Este
debe recibir el n´umero que se sumar´a y restar´a para encriptar y desencriptar y guardarlo como atributo.
Adem´as, como debemos mostrar si el objeto pudo ser creado con ´exito, y el constructor no puede retornar
nada, agregamos otro atributo a la clase que indique si el objeto se cre´o bien o no.
Para el m´etodo encriptar lo que primero tenemos que hacer es revisar si el objeto se cre´o con ´exito. Si
no fue as´ı retornamos el mensaje de error. Luego tenemos que determinar si el usuario desea encriptar o
desencriptar, para saber si sumar o restar a cada caracter. A continuaci´on, debemos sumar (o restar) tantas
posiciones como valor determinado por el usuario en el constructor, a cada car´acter; si se ”pasa”de la z,
volvemos a la a. Como sabemos que los char se pueden operar como si fueran enteros, basta con sumar (o
restar) la cantidad adecuada a cada char del String.
IIC1103 – Cap´ıtulo 5: Strings 24
Posible soluci´on
public class Codificador {
private int millave ;
private boolean habilitado;
public Codificador(int llave ) {
if (( llave >= 0) && (llave <= 26)) {
millave = llave;
habilitado = true;
} else {
habilitado = false;
}
}
public String encriptar(String mensaje , boolean encriptar) {
String encriptado = "";
int cero = ’a’ - 1;
int llaveActual = millave ;
if (! encriptar)
llaveActual *= -1;
for (int i = 0; i < mensaje .length (); i++) {
char letra = mensaje . charAt (i);
int valor = letra;
if (letra != ’ ’) {
valor = letra + llaveActual - cero;
if (encriptar) {
if (valor > 26)
valor %= 26;
} else {
if (valor < 0)
valor = 26 + valor ;
}
valor += cero;
}
encriptado += (char) ( valor );
}
if ( habilitado)
return encriptado;
return "#ERROR#";
}
}
IIC1103 – Cap´ıtulo 5: Strings 25
Problema 13: Encriptar
Enunciado
Se desea enviar mensajes encriptados. Para ello, Ud. deber´a crear un algoritmo que encripte un mensaje
cualquiera, siguiendo esta estrategia: Ordene el mensaje ingresado, de manera que forme un cuadrado perfecto
(el n´umero de filas es igual al n´umero de columnas). No debe considerar los espacios en blanco. En caso de
que el n´umero de letras no den un cuadrado perfecto, a˜nada el caracter de relleno ”@”. Finalmente, lea el
mensaje de arriba abajo y de izquierda a derecha. A continuaci´on se presenta un ejemplo:
// Mensaje original
"Mensaje a ser encriptado"
// Este seria nuestro cuadrado , se eliminan los espacios y se agregan @
Mensa
jease
rencr
iptad
o@@@@
// Mensaje resultante
" Mjrioeeep@nant@ssca@aerd@"
Aqu´ı se encuentra la clase principal Encriptador que hace uso de la clase Cypher. Ud. deber´a implementar
todos los m´etodos de la clase Cypher que son invocados por el Encriptador:
import iic1103Package.*;
public class Encriptador {
public static void main(String [] args) {
Cypher c = new Cypher ();
String msg = Usuario .texto ("Ingrese el mensaje a encriptar");
// Quitar espacios del mensaje ingresado
msg = c.QuitarEspacios(msg);
// Determinar el tamanio del Cuadrado (nro. filas = nro. columnas )
int nro_filas = c. CuadradoPerfecto(msg);
// Algoritmo de encriptacion
String msg2 = c. Encriptar(msg , nro_filas);
Usuario .mensaje (msg2);
}
}
Criterios de soluci´on
M´etodo QuitarEspacios: En este m´etodo tenemos que recorrer el String e ir obteniendo cada caracter
con el m´etodo charAt y revisar si es igual al caracter que representa el espacio. Si no es igual lo
concatenamos al String final. As´ı el String que retornamos no contiene ning´un espacio.
M´etodo CuadradoPerfecto: En este m´etodo tenemos que determinar el n´umero de filas (igual al
n´umero de columnas). Para esto utilizamos el m´etodo Math.sqrt con el largo del String, considerando
que si la raiz no es exacta tenemos que sumar uno al resultado para poder considerar todas las letras
del mensaje.
M´etodo Encriptar: Lo primero que tenemos que hacer es revisar si el mensaje ocupa todas las posi-
ciones del cuadrado. De no ser as´ı debemos rellenar los caracteres que faltan con ’@’.
Despu´es para encriptar lo importante es recorrer bien el String. As´ı, partimos desde el comienzo y con
un ciclo vamos recorriendo todo el String. Dentro de este ciclo implementamos otro, el cual vaya ob-
teniendo los caracteres para concatenar en la respuesta final. Para obtener los caracteres tenemos que
avanzar tantas posiciones como el n´umero de columnas tenga el cuadrado, as´ı estaremos recorriendo el
cuadrado leyendo por columna.
IIC1103 – Cap´ıtulo 5: Strings 26
Posible soluci´on
public class Cypher {
public String Encriptar(String s, int total) {
String respuesta = "";
// aniadir caracteres extra
while (s.length () < (total * total ))
s = s + "@";
// llenar el cuadrado
for (int i = 0; i < total ; i++) {
for (int j = i; j < s. length (); j = j + total )
respuesta = respuesta + s.charAt (j);
}
return respuesta;
}
public int CuadradoPerfecto(String s) {
int total = (int) Math.sqrt(s.length ());
if ( total * total != s. length ())
total ++;
return total;
}
public String QuitarEspacios(String s) {
String otro = "";
for (int i = 0; i < s. length (); i++) {
if (s.charAt (i) != ’ ’)
otro += s.charAt (i);
}
return otro;
}
}
IIC1103 – Cap´ıtulo 5: Strings 27
Problema 14: Nombre de Usuario
Enunciado
Cada alumno de la Universidad tiene un nombre de usuario, que es el nombre al cual se le env´ıa e-mail en
el dominio de la Universidad. Este nombre de usuario se determina a partir del nombre real del alumno y
est´a compuesto por 8 caracteres que pueden ser letras o n´umeros.
Escriba la clase NombredeUsuario, que tiene como atributos al menos el nombre real del alumno, el nombre
de usuario inicial, y el nombre de usuario final. Adem´as, esta clase debe tener al menos los siguientes tres
m´etodos:
Un constructor, que recibe como par´ametros cuatro strings, correspondientes al primer nombre, segundo
nombre, primer apellido y segundo apellido del alumno. Si el alumno tiene s´olo un nombre, el par´ametro
correspondiente al segundo nombre es un String vac´ıo. En el atributo, el nombre real del alumno
debe quedar escrito en la forma familiar <primer nombre> <segundo nombre> <primer apellido>
<segundo apellido>, o bien <primer nombre> <primer apellido>
<segundo apellido> (notar que hay espacios en blanco).
Un m´etodo nombreUsuarioInicial, que determina el nombre de usuario inicial del alumno, a partir de
su nombre real, y lo guarda en el atributo correspondiente. El nombre de usuario inicial est´a formado
por la inicial del primer nombre, seguido por la inicial del segundo nombre, y seguido por las seis
primeras letras del primer apellido (para totalizar los 8 caracteres) Si el alumno no tiene segundo
nombre, entonces la inicial del segundo nombre es reemplazada por la segunda letra del primer nombre.
Si el primer apellido tiene menos de seis letras, entonces las letras faltantes son reemplazadas por las
primeras letras del segundo apellido.
Un m´etodo nombreUsuarioFinal , que recibe como par´ametro un string con todos los nombres de
usuario v´alidos en la Universidad (cada uno separado por un punto), y que determina el nombre de
usuario final del alumno y lo guarda en el atributo correspondiente. Para determinar el nombre de
usuario final hay que revisar el string de nombres de usuario v´alidos. Si el nombre de usuario inicial
no aparece en el string, entonces el nombre de usuario final es igual al inicial. En cambio, si el nombre
de usuario inicial aparece en el string, entonces el nombre de usuario final se determina de la siguiente
manera: se elige aleatoriamente un n´umero entre 1 y 7, y se cambia la letra que est´a en esa posici´on
en el nombre de usuario inicial por uno de los d´ıgitos 1 al 9, tambi´en elegido aleatoriamente.
Suponga que siempre la cantidad de letras del apellido paterno m´as la cantidad de letras del apellido materno
es al menos 6.
Criterios de soluci´on
Atributos: Lo primero que tenemos que hacer es declarar los atributos de la clase como nos indican
el enunciado. Para esto utilizamos 3 Strings para guardar el nombre de usuario inicial, el nombre real
y el nombre de usuario final. Adem´as podemos guardar los nombres y apellidos del usuario en otros
Strings.
Constructor: Recibimos los par´ametros que nos indica el enunciado y revisamos si el segundo nombre
viene nulo. Seg´un esto formamos el nombre real.
M´etodo nombreUsuarioInicial : Lo primero que tenemos que hacer es revisar si el usuario tiene
segundo nombre. Si es as´ı tomamos el primer caracter (con el m´etodo charAt()) del primer nombre y
el primer caracter del segundo nombre. Si no, tomamos los dos primeros caracteres del primer nombre.
Concatenamos los caracteres obtenidos en el atributo que representa el nombre de usuario inicial.
Luego, revisamos, con el m´etodo length(), si el apellido del usuario tienen m´as de 6 letras. Si es as´ı,
con el m´etodo substring obtenemos las 6 primeras letras y las concatenamos al nombre de usuario
IIC1103 – Cap´ıtulo 5: Strings 28
inicial. Si no, calculamos cuantas letras nos faltan y adem´as del primer apellido concatenamos las letras
que faltan del segundo apellido.
M´etodo nombreUsuarioFinal: Recibimos el String con los nombres de usuario ya existente y utilizando
el m´etodo contains revisamos si el nombre de usuario formado est´a contenido en los nombres de
usuarios recibidos. Si es as´ı, generamos aleatoriamente dos n´umeros: uno que determine la posici´on
y otro que sea el n´umero a intercalar en esa posici´on. Luego con el m´etodo substring separamos
el nombre de usuario inicial en dos y luego concatenamos la primera mitad, m´as el d´ıgito generado
aleatoriamente m´as la segunda mitad y tenemos el nombre de usuario final.
Posible soluci´on
import iic1103Package.*;
public class NombredeUsuario {
private String nombreReal;
private String nomUsuIni;
private String nombreUsuario;
private String nombre1 , nombre2 , apellido1 , apellido2;
public NombredeUsuario(String nom1 , String nom2 , String ap1 , String ap2) {
nombre1 = nom1;
nombre2 = nom2;
apellido1 = ap1;
apellido2 = ap2;
if (nom2.length () == 0) {
nombreReal = nombre1 + " " + apellido1 + " " + apellido2;
} else {
nombreReal = nombre1 + " " + nombre2 + " " + apellido1 + " "
+ apellido2;
}
}
public void nombreUsuarioInicial() {
if ( nombre2 .length () == 0) {
nomUsuIni = "" + nombre1 .charAt (0) + nombre1 .charAt (1);
} else {
nomUsuIni = "" + nombre1 .charAt (0) + nombre2 .charAt (0);
}
if ( apellido1.length () >= 6) {
nomUsuIni = nomUsuIni + apellido1. substring(0, 6);
} else {
int k = 6 - apellido1. length ();
nomUsuIni = nomUsuIni + apellido1 + apellido2.substring(0, k);
}
}
public void nombreUsuarioFinal(String usuarios ) {
if (! usuarios .contains ( nomUsuIni)){
nombreUsuario = nomUsuIni;
} else {
int p = Aleatorio.entero (1, 7);
int q = Aleatorio.entero (1, 9);
nombreUsuario = nomUsuIni.substring(0, p) + q
+ nomUsuIni. substring(p + 1, 8);
}
}
}
IIC1103 – Cap´ıtulo 5: Strings 29
Problema 15: Mensaje Oculto
Enunciado
El servicio secreto le ha encomendado la tarea de implementar un programa que pueda descifrar mensajes
ocultos que se esperan recibir de un agente encubierto en la mafia de las revistas de far´andula.
Se espera que este agente utilice el primer y ´ultimo caracter de cada l´ınea de los textos para esconder los
mensajes, de manera que para leer el mensaje se deben leer los primeros caracteres de cada l´ınea desde arriba
hacia abajo y luego seguir con los ´ultimos caracteres de cada l´ınea pero desde abajo hacia arriba (salvo la
´ultima l´ınea, en la cu´al s´olo se considera en el mensaje su primer car´acter). Adem´as, si el car´acter es una letra
may´uscula, implicar´a que comienza una nueva palabra en el mensaje oculto, mientras que si es un punto ‘.’
o coma ‘,’ ser´a equivalente a un espacio (que separar´a dos palabras contiguas). Por ejemplo, si tenemos el
siguiente texto:
Mientras con ansias a su perro
esperaba, muchas preocupaciones
Gustavo ten´ıa. Esperar
unos minutos m´as su espiritu
socavaba escuchando el tic tac
tembloroso de su reloj. Sin embargo,
a pesar de la larga espera, finalmente
Einstein, su perro, volvi´o a su apreciado habitat
sembrando la alegr´ıa en su querido amigo.
El mensaje resultante ser´a “Me Gusta Este curso” (no se preocupe de may´usculas y min´usculas en el mensaje
resultante).
En concreto, se le solicita que escriba una clase Decifrador con un constructor que reciba el texto a descifrar
y un m´etodo descubrirMensaje que entregue como resultado el mensaje descifrado a partir del texto (sin
perjuicio de que adem´as agregue todos los atributos y m´etodos que estime necesarios). De esta manera, su
clase deber´a poder ser usada de la siguiente forma:
String mensaje = "Mientras con ansias a su perro n esperaba, muchas preocupacionesn
Gustavo ten´ıa. Esperarn unos minutos m´as su esp´ıritun socavaba escuchando el tic tacn
tembloroso de su reloj. Sin embargo,n a pesar de la larga espera, finalmente nEinstein,
su perro, volvi´o a su habitatn sembrando alegr´ıa en su querido amigo.";
Decifrador decifrador = new Decifrador(mensaje);
Usuario.mensaje(decifrador.descubrirMensaje());
NOTA: Puede suponer que no habr´a caracteres con tilde (´a, ´e, ´ı,. . . ) ni ˜n al principio y final de cada l´ınea.
Criterios de soluci´on
Constructor: Simplemente recibimos como par´ametro un String que represente el mensaje y lo asigna-
mos al atributo de la clase.
M´etodo descubrirMensaje: En este m´etodo recorremos el String buscando el caracter de fin de l´ınea
(obtenemos cada caracter con el m´etodo charAt()). Cuando encontramos el salto de l´ınea obtenemos
el caracter que est´a a la izquierda (que ser´ıa el ´ultimo caracter de la l´ınea) y el que est´a a la derecha
(que ser´ıa el primer caracter de la siguiente l´ınea). Revisamos si se trata de un caracter especial (como
IIC1103 – Cap´ıtulo 5: Strings 30
punto ‘.’ o coma ‘,’ o una letra may´uscula) para agregar espacios cuando corresponda y formamos dos
strings: uno que represente las letras iniciales de cada l´ınea y otro las finales, tomando en cuenta que
al que represente las letras finales hay que ir agregando los nuevos caracteres al inicio y no al final.
As´ı despu´es concatenamos estos dos Strings y tenemos el mensaje descifrado.
Posible soluci´on
public class Descifrador {
private String texto;
public Descifrador(String texto) {
this. texto = texto;
}
public String descubrirMensaje() {
String resultadoIzquierdo = "" + texto.charAt (0);
String resultadoDerecho = "";
char caracterIzquierdo;
char caracterDerecho;
for (int i = 1; i < texto .length () - 1; i++) {
char caracterActual = texto.charAt (i);
if (caracterActual == ’n’) {
caracterIzquierdo = texto.charAt (i - 1);
caracterDerecho = texto .charAt (i + 1);
resultadoIzquierdo += interpretarCaracter(caracterDerecho);
resultadoDerecho = interpretarCaracter( caracterIzquierdo)
+ resultadoDerecho;
}
}
return resultadoIzquierdo + resultadoDerecho;
}
private String interpretarCaracter(char caracter ) {
if ( caracter >= ’A’ && caracter <= ’Z’) {
return " " + caracter ;
} else if (caracter == ’.’ || caracter == ’,’) {
return " ";
}
return "" + caracter ;
}
}
IIC1103 – Cap´ıtulo 5: Strings 31
Problema 16: Tap Code
Enunciado
El Tap Code es una forma de encriptar mensajes usada por prisioneros en Vietnam. Es un m´etodo muy
simple que consiste en traducir cada letra de un mensaje en una serie de sonidos hechos con metal, madera,
etc. (”taps”) y pausas. Tambi´en puede ser representado gr´aficamente. En este caso cada letra se traduce en
dos series de puntos separados por un espacio, que representan dos n´umeros indicando la fila y columna que
corresponde a la letra en una matriz de claves de 5x5. Por ejemplo, dada la matriz de la figura, la letra ”D”
est´a en la fila 1, columna 4, por lo que se representa por los puntos ”. ....”(1, 4).
La palabra ”MENSAJE” se traducir´ıa de la siguiente manera.
Las letras de una palabra tambi´en van separadas entre s´ı por 1 espacio, al final de la serie de puntos no debe
ir un espacio. Otras consideraciones: la letra K se considera que es una C, la letra ˜N se considera como si
fuera N, se ignora todo otro s´ımbolo fuera de la matriz de claves.
Se pide que implemente el m´etodo aTap de la clase Cipher que recibe dos Strings, uno contiene el mensaje
original, y el otro un String con los caracteres de la matriz, ambos Strings en may´usculas. El m´etodo aTap
devuelve un String conteniendo la serie de puntos equivalentes en el Tap Code. Note que si recibe como
mensaje un String vac´ıo o nulo, debe retornar el mismo mensaje original sin ning´un cambio.
import iic1103Package.*;
public class Principal {
public static void main(String [] args) {
String matriz = " ABCDEFGHIJLMNOPQRSTUVWXYZ";
Cypher c = new Cypher ();
String mensaje = Usuario . texto("Mensaje ?");
// Convierte el mensaje a mayusculas
mensaje = mensaje . toUpperCase();
Usuario .mensaje (c.aTap(mensaje , matriz ));
}
}
public class Cypher {
public String aTap(String original , String matriz ) {
// Implementar el metodo que convierte a original en una
// lista de puntos siguiendo las reglas del TapCode
}
}
Criterios de soluci´on
Lo primero que tenemos que hacer en el m´etodo aTap es revisar que el String original recibido como par´ametro
no sea vac´ıo. Si es as´ı, simplemente retornamos el mismo String.
IIC1103 – Cap´ıtulo 5: Strings 32
Si el String no est´a vac´ıo debemos recorrerlo con un ciclo para obtener cada letra que lo compone, utilizando
para esto el m´etodo charAt. Al obtener la letra debemos revisar si se trata de una C o una ˜N y cambiarlas
a C y N respectivamente.
Luego tenemos que encontrar la posici´on de la letra en la matriz recibida como par´ametro. Si vemos la matriz
como un String extendido podemos ver que la fila de la letra estar´a dada por la posici´on de la letra en el
String divido en 5 (ya que son 5 filas y 5 columnas). Y la columna de la letra estar´a dada por el resto de
la divisi´on de la posici´on de la letra en el String por 5. Despu´es de eso s´olo tenemos que imprimir tantos
puntos como la fila y la columna encontrada, separando cada uno con un espacio.
Posible soluci´on
public String aTap(String original , String matriz ) {
if (( original == null) || original .equals ("")) {
return original ;
}
String puntos = "";
for (int i = 0; i < original .length (); i++) {
String letra = "" + original .charAt (i);
if (letra.equals ("K")) {
letra = "C";
} else if (letra.equals ("N")) {
letra = "N";
}
int n = -1, m = -1;
if (matriz .indexOf (letra ) >= 0) {
n = matriz .indexOf (letra ) / 5;
m = matriz .indexOf (letra ) - n * 5;
}
if (n >= 0 && n >= 0) {
for (int j = 0; j <= n; j++) {
puntos = puntos + ".";
}
puntos = puntos + " ";
for (int j = 0; j <= m; j++) {
puntos = puntos + ".";
}
}
puntos = puntos + " ";
}
// NO DEBE INCLUIR UN ESPACIO AL FINAL
if ( puntos .length () > 0) {
puntos = puntos . substring(0, puntos .length () - 1);
}
return puntos ;
}
IIC1103 – Cap´ıtulo 5: Strings 33
Problema 17: Integrantes Familia
Enunciado
Usted deber´a realizar un programa que permita manejar a los integrantes de distintas familias, as´ı como
a los pasatiempos de cada uno de esos integrantes. Para ello contar´a con un m´etodo main que ya viene
implementado.
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.
No puede utilizar el m´etodo contains de la clase String.
Incremento 1
En este primer incremento deber´a definir lo b´asico de las clases Familia y Persona, de modo de poder
crearlas. Una Persona est´a caracterizada por su nombre, su edad y su g´enero, el cual se representa con un
0 si es hombre o un 1 en caso que sea mujer. Adem´as cada persona tiene sus pasatiempos, los cuales se
representan con un string en el cual se van concatenando los pasatiempos que se van agregando. Su clase
Persona debe cumplir con los usos dados en el main dado, el cual usted no puede modificar.
Por su parte Familia est´a caracterizado por los apellidos de la familia y por hasta 5 personas que son los
integrantes de la familia. Al igual que Persona, Familia debe poder ser utilizada con el main predefinido,
por lo que debe coincidir los nombres de los m´etodos que ah´ı se encuentran as´ı como los par´ametros de cada
uno.
Incremento 2
Ahora que ya est´an creadas las familias, debe agregar los m´etodos necesarios a sus clases para que sea posible
mostrar en consola cada familia. Una familia se muestra indicando sus apellidos y el nombre, edad y g´enero
de cada uno de sus integrantes. Este es un ejemplo de como se muestra una familia en consola:
***************************************************
Familia : Palma Sepulveda
Juan (25 - Hombre )
Maria (43 - Mujer)
Pedro (12 - Hombre )
Pablo (48 - Hombre )
***************************************************
Adem´as cada familia debe ser capaz de retorna el promedio de edad de la familia, para que as´ı el main pueda
mostrarlos.
Incremento 3
Por ´ultimo debe ser posible buscar el n´umero de integrantes que tiene un cierto pasatiempo en cada familia.
Pudiendo tambi´en realizar esta b´usqueda en un g´enero en particular. Nuevamente debe cumplir con lo defi-
nido en el main.
import iic1103Package.*;
public class Principal {
public static void main(String [] args) {
/* ***********************************************************************
* Iteracion 1
*/
// Creamos todas las familias con sus respectivas personas y pasatiempos
Familia f1 = new Familia ("Palma Sepulveda");
Persona p11 = new Persona (" Juan", 25, 0);
p11. agregarPasatiempo("Futbol ");
p11. agregarPasatiempo("Piano ");
Persona p12 = new Persona (" Maria", 43, 1);
p12. agregarPasatiempo("Leer");
Persona p13 = new Persona (" Pedro", 12, 0);
p13. agregarPasatiempo("TV");
p13. agregarPasatiempo("Futbol ");
IIC1103 – Cap´ıtulo 5: Strings 34
Persona p14 = new Persona (" Pablo", 48, 0);
p14. agregarPasatiempo("Leer");
p14. agregarPasatiempo("Futbol ");
p14. agregarPasatiempo("Comer ");
f1. agregarIntegrante(p11);
f1. agregarIntegrante(p12);
f1. agregarIntegrante(p13);
f1. agregarIntegrante(p14);
Familia f2 = new Familia ("Langdon Alarcon ");
Persona p21 = new Persona (" Carolina ", 13, 1);
p21. agregarPasatiempo("Bailar ");
p21. agregarPasatiempo("Leer");
Persona p22 = new Persona (" Isabel ", 17, 1);
p22. agregarPasatiempo("Cantar ");
p22. agregarPasatiempo("Leer");
p22. agregarPasatiempo("Futbol ");
Persona p23 = new Persona (" Jose", 30, 0);
p23. agregarPasatiempo("Futbol ");
p23. agregarPasatiempo("Comer ");
f2. agregarIntegrante(p21);
f2. agregarIntegrante(p22);
f2. agregarIntegrante(p23);
Familia f3 = new Familia ("Eterovic Zavala ");
Persona p31 = new Persona (" Yadran ", 45, 0);
p31. agregarPasatiempo("Tenis ");
p31. agregarPasatiempo("Leer");
Persona p32 = new Persona (" Tere", 19, 1);
p32. agregarPasatiempo("Comer ");
p32. agregarPasatiempo("Leer");
p32. agregarPasatiempo("Bailar ");
Persona p33 = new Persona (" Sole", 30, 1);
p33. agregarPasatiempo("Leer");
Persona p34 = new Persona (" Sebastian", 52, 0);
p33. agregarPasatiempo("Tenis ");
p33. agregarPasatiempo("Cocinar ");
p33. agregarPasatiempo("Comer ");
Persona p35 = new Persona (" Francisco", 35, 0);
p33. agregarPasatiempo("Futbol ");
p33. agregarPasatiempo("Leer");
Persona p36 = new Persona (" Matias ", 25, 0);
p33. agregarPasatiempo("Futbol ");
p33. agregarPasatiempo("Cocinar ");
f3. agregarIntegrante(p31);
f3. agregarIntegrante(p32);
f3. agregarIntegrante(p33);
f3. agregarIntegrante(p34);
f3. agregarIntegrante(p35);
// El metodo agregar persona debe retornar false si no es posible
// hacerlo porque ya esta llena la familia .
if (! f3.agregarIntegrante(p36)) {
Usuario .mensajeConsola("No se pudo agregar " + p36.getNombre()
+ " a la familia " + f3.getApellidos());
}
Familia f4 = new Familia ("Peralta Jara");
Persona p41 = new Persona (" Fernando ", 26, 0);
p41. agregarPasatiempo("Tenis ");
p41. agregarPasatiempo("Leer");
p41. agregarPasatiempo("Cantar ");
Persona p42 = new Persona (" Cata", 24, 1);
p42. agregarPasatiempo("Bailar ");
p42. agregarPasatiempo("Yoga");
p42. agregarPasatiempo("Cocinar ");
p42. agregarPasatiempo("Viajar ");
f4. agregarIntegrante(p41);
f4. agregarIntegrante(p42);
/* ***********************************************************************
* Iteracion 2
*/
// Mostramos cada familia
f1. mostrarFamilia();
f2. mostrarFamilia();
f3. mostrarFamilia();
f4. mostrarFamilia();
IIC1103 – Cap´ıtulo 5: Strings 35
// Mostramos el promedio de edad de cada familia
Usuario .mensajeConsola("Edad Familia : " + f1. getApellidos() + " - "
+ f1.promedioEdad());
Usuario .mensajeConsola("Edad Familia : " + f2. getApellidos() + " - "
+ f2.promedioEdad());
Usuario .mensajeConsola("Edad Familia : " + f3. getApellidos() + " - "
+ f3.promedioEdad());
Usuario .mensajeConsola("Edad Familia : " + f4. getApellidos() + " - "
+ f4.promedioEdad());
/* ***********************************************************************
* Iteracion 3
*/
// Buscamos la cantidad de personas con pasatiempo Futbol en cada
// familia
Usuario .mensajeConsola("Personas que les gusta el futbol Familia : "
+ f1.getApellidos() + " - "
+ f1. integrantesConPasatiempo("Futbol "));
Usuario .mensajeConsola("Personas que les gusta el futbol Familia : "
+ f2.getApellidos() + " - "
+ f2. integrantesConPasatiempo("Futbol "));
Usuario .mensajeConsola("Personas que les gusta el futbol Familia : "
+ f3.getApellidos() + " - "
+ f3. integrantesConPasatiempo("Futbol "));
Usuario .mensajeConsola("Personas que les gusta el futbol Familia : "
+ f4.getApellidos() + " - "
+ f4. integrantesConPasatiempo("Futbol "));
// Ahora mostramos la cantidad de mujeres que les gusta leer por cada
// familia
Usuario .mensajeConsola("Mujeres que les gusta leer Familia : "
+ f1.getApellidos() + " - "
+ f1. integrantesConPasatiempoPorGenero("Leer", 1));
Usuario .mensajeConsola("Mujeres que les gusta leer Familia : "
+ f2.getApellidos() + " - "
+ f2. integrantesConPasatiempoPorGenero("Leer", 1));
Usuario .mensajeConsola("Mujeres que les gusta leer Familia : "
+ f3.getApellidos() + " - "
+ f3. integrantesConPasatiempoPorGenero("Leer", 1));
Usuario .mensajeConsola("Mujeres que les gusta leer Familia : "
+ f4.getApellidos() + " - "
+ f4. integrantesConPasatiempoPorGenero("Leer", 1));
}
}
Criterios de soluci´on
Clase Persona
• Atributos: Declaramos los atributos necesarios seg´un nos indican en el enunciado: dos String, uno
para el nombre y otro para los pasatiempos y dos enteros, uno para representar la edad y otro
para representar el g´enero.
• Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametros
el nombre, la edad y el genero y los asigna a los atributos correspondientes.
• M´etodo agragarPasatiempo: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe
como par´ametro un String con el hobbie a agregar y tenemos que concatenarlo al String que
almacena los pasatiempos.
• Getters: Seg´un el uso dado en la clase Principal necesitamos 3 m´etodos get para obtener el nombre,
la edad y el g´enero.
• M´etodo tienePasatiempo: Este m´etodo sirve para revisar si la persona tiene un determinado
pasatiempo (para cumplir con lo pedido en el incremento 3), puede hacerse tambi´en s´olo en la
clase Familia. Lo que hacemos es buscar el pasatiempo generando todos los substrings desde la
lista de pasatiempos que tengan el mismo largo que el pasatiempo recibido y comparar hasta
encontrar alguna coincidencia.
• M´etodo mostrar: Revisamos el g´enero de la persona y seg´un eso mostramos en Consola su edad
seguida de ’Hombre’ o ’Mujer’ seg´un corresponda.
IIC1103 – Cap´ıtulo 5: Strings 36
Clase Familia:
• Atributos: Declaramos los atributos necesarios seg´un lo que se nos indica en el enunciado: un String
para guardar los apellidos y cuatro objetos de la clase Persona que representen a los integrantes.
• Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro
un String con los apellidos y lo asigna al atributo correspondiente.
• M´etodo agregarIntegrante: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe
como par´ametro un objeto de la clase Persona. Tenemos que revisar a qu´e objeto, de los 4 que
tenemos como atributos, debemos asignarlo, revisando cu´al de ellos es todav´ıa null. Retornamos
true o false seg´un se pudo o no asignar el integrante.
• M´etodo getApellidos: Retorna los apellidos de la familia.
• M´etodo promedioEdad: Recorremos todas las personas y obtenemos su edad (cuidando que el
integrante no sea null) calculando con esto el promedio.
• M´etodo mostrarFamilia: Mostramos en la consola los apellidos de la familia y por cada persona
mostramos su edad y si es hombre o mujer.
• M´etodo integrantesConPasatiempo: Para no implementar un m´etodo dos veces simplemente
llamamos al m´etodo integrantesConPasatiempoPorGenero definiendo un valor inv´alido para el
g´enero.
• M´etodo integrantesConPasatiempoPorGenero: Recorremos todas las personas y en cada una
revisamos que no sea nula y que tenga el pasatiempo solicitado (llamando al m´etodo que imple-
mentamos en la clase Persona). Adem´as, en caso que el g´enero sea v´alido, tambi´en revisamos que
el genero de la persona corresponda. Si se cumplen ambas condiciones aumentamos el contador
de personas, el cual retornamos al finalizar el m´etodo.
Posible soluci´on
import iic1103Package.*;
public class Familia {
// Definimos los atributos necesarios
private String apellidos;
// Definimos las personas que pueden integrar la familia
private Persona integrante1;
private Persona integrante2;
private Persona integrante3;
private Persona integrante4;
private Persona integrante5;
public Familia (String apellidos) {
this. apellidos = apellidos;
}
public Persona obtenerPersona(int idx) {
// Obtenemos la persona segun el indice de ella
if (idx == 0)
return integrante1;
else if (idx == 1)
return integrante2;
else if (idx == 2)
return integrante3;
else if (idx == 3)
return integrante4;
else
return integrante5;
}
public boolean agregarIntegrante(Persona p) {
// Para agregar un nuevo integrante buscamos aquel que aun sea nulo
if ( integrante1 == null) {
integrante1 = p;
} else if (integrante2 == null) {
integrante2 = p;
IIC1103 – Cap´ıtulo 5: Strings 37
} else if (integrante3 == null) {
integrante3 = p;
} else if (integrante4 == null) {
integrante4 = p;
} else if (integrante5 == null) {
integrante5 = p;
} else {
// Si no hay ninguno vacio entonces retornamos false
return false;
}
return true;
}
public double promedioEdad() {
// Declaramos una variable donde acumularemos
double promedio = 0;
int count = 0;
// Recorremos todas las personas
for (int i = 0; i < 5; i++) {
Persona p = obtenerPersona(i);
if (p != null) {
// En caso de estar la persona acumulamos su edad
promedio += p.getEdad ();
count ++;
}
}
return promedio / count;
}
public int integrantesConPasatiempo(String hobbie ) {
// Llamamos al metodo que busca con genero definiendo un valor invalido
// para el genero
return integrantesConPasatiempoPorGenero(hobbie , -1);
}
public int integrantesConPasatiempoPorGenero(String hobbie , int genero ) {
int count = 0;
// Recorremos todas las personas
for (int i = 0; i < 5; i++) {
Persona p = obtenerPersona(i);
// Revisamos que no sea nula y que tenga el pasatiempo solicitado.
// Ademas en caso de que el
// genero sea valido tambien restringimos por el
if (p != null && p. tienePasatiempo(hobbie )
&& (genero == -1 || p.getGenero() == genero ))
count ++;
}
return count;
}
public void mostrarFamilia() {
// Mostramos los apellidos y luego a cada una de las personas
Usuario .mensajeConsola(" ***************************************************");
Usuario .mensajeConsola("Familia : " + apellidos);
for (int i = 0; i < 5; i++) {
Persona p = obtenerPersona(i);
if (p != null) {
p.mostrar ();
}
}
Usuario .mensajeConsola(" ***************************************************");
}
public String getApellidos() {
return apellidos;
}
}
import iic1103Package.*;
public class Persona {
// Definimos los atributos minimos necesarios
private String nombre ;
private int edad;
private int genero ;
private String pasatiempos;
IIC1103 – Cap´ıtulo 5: Strings 38
public Persona (String nombre , int edad , int genero ) {
// Inicializamos los valores para la persona , en un principio no tiene
// pasatiempos
this. nombre = nombre ;
this.edad = edad;
this. genero = genero ;
this. pasatiempos = "";
}
public void agregarPasatiempo(String hobbie ) {
// Al agregar un pasatiempo lo agregamos al String que los representa
pasatiempos += " - " + hobbie ;
}
public String getNombre() {
return nombre ;
}
public int getEdad () {
return edad;
}
public int getGenero() {
return genero ;
}
public boolean tienePasatiempo(String hobbie ) {
// Buscamos el pasatiempo generando todos los substrings desde la lista
// de pasatiempos que tengan el mismo largo que el pasatiempo recibido
for (int i = 0; i <= pasatiempos.length () - hobbie .length (); i++) {
String aux = pasatiempos.substring(i, i + hobbie .length ());
if (aux. equalsIgnoreCase(hobbie )) {
return true;
}
}
return false;
}
public void mostrar () {
if ( genero == 0) {
Usuario .mensajeConsola( nombre + " (" + edad + " - Hombre )");
} else {
Usuario .mensajeConsola( nombre + " (" + edad + " - Mujer)");
}
}
}
IIC1103 – Cap´ıtulo 5: Strings 39
Problema 18: Modelos de Autom´ovil
Enunciado
Usted deber´a realizar un programa que permita manejar los modelos pertenecientes a distintas marcas de
autom´oviles, as´ı como las caracter´ısticas de estos modelos. Para ello deber´a trabajar con un m´etodo main
que ya viene implementado.
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 primer incremento deber´a definir lo b´asico de las clases Marca y Modelo, para poder crearlas. Un
Modelo est´a caracterizado por el nombre del modelo, el a˜no en que sali´o al mercado, y el tipo de veh´ıculo
que es, el cual se representa con un 0 si corresponde a un modelo sed´an, un 1 si se trata de un station wagon,
y un 2 en caso que sea una camioneta. Adem´as cada modelo tiene sus propias caracter´ısticas, las cuales se
representan con un string en el cual se van concatenando las caracter´ısticas que se van agregando al modelo.
Su clase Modelo debe cumplir con los usos dados en el main provisto, el cual usted no puede modificar.
Por su parte, una Marca est´a caracterizada por los modelos que componen su l´ınea de producci´on, pudiendo
ser hasta cuatro como m´aximo. Al igual que Modelo, la clase Marca debe poder ser utilizada con el main
predefinido, por lo que en su implementaci´on deben coincidir los nombres y par´ametros de los m´etodos que
ah´ı se encuentran.
Incremento 2
Ahora que ya est´an creadas las marcas y sus modelos, debe agregar los m´etodos necesarios a sus clases para
que sea posible mostrar en consola el cat´alogo de cada marca. Para una marca, este cat´alogo se muestra
indicando su nombre y, para cada uno de sus modelos, la informaci´on correspondiente al nombre del modelo,
su a˜no y su tipo. Por ejemplo, para una de las marcas el mensaje debe mostrarse como el siguiente:
***************************************************
Marca: Hyundai
Accent, 2008, Sedan
Sonata, 2007, Sedan
H-1, 2005, Station Wagon
***************************************************
Adem´as, cada marca debe ser capaz de retornar la cantidad de modelos del a˜no 2008 que posee en su
cat´alogo, para que as´ı el main pueda mostrar los mensajes correspondientes.
Incremento 3
Por ´ultimo, debe complementar sus clases de modo que sea posible imprimir el cat´alogo de cada marca
s´olo con los modelos correspondientes a un a˜no espec´ıfico, como tambi´en buscar el n´umero de modelos que
presenten una cierta caracter´ıstica en cada marca, permitiendo adicionalmente realizar esta b´usqueda para
un tipo de veh´ıculo en particular. Nuevamente debe cumplir con lo ya definido en el m´etodo main que se le
entrega al comenzar su trabajo.
IIC1103 – Cap´ıtulo 5: Strings 40
import iic1103Package.*;
public class Principal {
public static void main(String [] args) {
/** Incremento 1 */
// Creamos marcas y agregamos modelos con distintas caracteristicas
Marca marca1 = new Marca("Hyundai ");
Modelo modelo11 = new Modelo ("Accent ", 2008 , 0);
modelo11 . agregarCaracteristica("Llantas ");
modelo11 . agregarCaracteristica(" Alzavidrios Electricos");
modelo11 . agregarCaracteristica("Radio CD");
modelo11 . agregarCaracteristica("Mecanico ");
modelo11 . agregarCaracteristica("Aire Acondicionado");
Modelo modelo21 = new Modelo ("Sonata ", 2007 , 0);
modelo21 . agregarCaracteristica("Aire Acondicionado");
modelo21 . agregarCaracteristica(" Automatico");
modelo21 . agregarCaracteristica(" Neblineros");
modelo21 . agregarCaracteristica(" Alzavidrios Electricos");
modelo21 . agregarCaracteristica("Radio CD");
modelo21 . agregarCaracteristica("Alarma ");
modelo21 . agregarCaracteristica("Tapiz de cuero");
modelo21 . agregarCaracteristica("Air Bag");
modelo21 . agregarCaracteristica(" Direccion Asistida ");
Modelo modelo31 = new Modelo ("H-1", 2005 , 1);
modelo31 . agregarCaracteristica("Alarma ");
modelo31 . agregarCaracteristica("Mecanico ");
modelo31 . agregarCaracteristica("Radio CD");
modelo31 . agregarCaracteristica(" Direccion Asistida ");
marca1 .agregarModelo( modelo11 );
marca1 .agregarModelo( modelo21 );
marca1 .agregarModelo( modelo31 );
Marca marca2 = new Marca("Toyota ");
Modelo modelo12 = new Modelo ("Hilux", 2008 , 2);
modelo12 . agregarCaracteristica("4x4");
modelo12 . agregarCaracteristica("Llantas ");
modelo12 . agregarCaracteristica("Radio CD");
modelo12 . agregarCaracteristica("Mecanico ");
modelo12 . agregarCaracteristica(" Neblineros");
modelo12 . agregarCaracteristica(" Direccion Asistida ");
modelo12 . agregarCaracteristica("Aire Acondicionado");
modelo12 . agregarCaracteristica("Air Bag");
Modelo modelo22 = new Modelo ("Yaris", 2007 , 0);
modelo22 . agregarCaracteristica("Alarma ");
modelo22 . agregarCaracteristica("Aire Acondicionado");
modelo22 . agregarCaracteristica("Radio CD");
modelo22 . agregarCaracteristica("Mecanico ");
modelo22 . agregarCaracteristica(" Alzavidrios Electricos");
modelo22 . agregarCaracteristica(" Direccion Asistida ");
Modelo modelo32 = new Modelo ("Auris", 2008 , 1);
modelo32 . agregarCaracteristica(" Neblineros");
modelo32 . agregarCaracteristica(" Alzavidrios Electricos");
modelo32 . agregarCaracteristica("Air Bag");
modelo32 . agregarCaracteristica(" Automatico");
modelo32 . agregarCaracteristica("Radio CD");
Modelo modelo42 = new Modelo ("Corolla ", 2006 , 0);
modelo42 . agregarCaracteristica("Radio CD");
modelo42 . agregarCaracteristica("Alarma ");
modelo42 . agregarCaracteristica(" Automatico");
modelo42 . agregarCaracteristica("Tapiz de cuero");
modelo42 . agregarCaracteristica(" Alzavidrios Electricos");
modelo42 . agregarCaracteristica("Aire Acondicionado");
modelo42 . agregarCaracteristica(" Neblineros");
modelo42 . agregarCaracteristica("Air Bag");
modelo42 . agregarCaracteristica(" Direccion Asistida ");
Modelo modelo52 = new Modelo ("Yaris Sport", 2008 , 1);
modelo52 . agregarCaracteristica("Radio CD");
modelo52 . agregarCaracteristica(" Alzavidrios Electricos");
marca2 .agregarModelo( modelo12 );
marca2 .agregarModelo( modelo22 );
marca2 .agregarModelo( modelo32 );
marca2 .agregarModelo( modelo42 );
if (! marca2 . agregarModelo(modelo52 )) {
Usuario .mensajeConsola("No se pudo agregar el modelo "
+ modelo52 . getModelo() + " a la marca "
+ marca2 .getNombre());
IIC1103 – Cap´ıtulo 5: Strings 41
}
Marca marca3 = new Marca("Mercedes Benz");
Modelo modelo13 = new Modelo ("C 200 K", 2008 , 1);
modelo13 . agregarCaracteristica("Llantas ");
modelo13 . agregarCaracteristica("Radio CD");
modelo13 . agregarCaracteristica(" Alzavidrios Electricos");
modelo13 . agregarCaracteristica(" Automatico");
modelo13 . agregarCaracteristica(" Neblineros");
modelo13 . agregarCaracteristica("Alarma ");
modelo13 . agregarCaracteristica("Tapiz de cuero");
modelo13 . agregarCaracteristica("Air Bag");
modelo13 . agregarCaracteristica(" Direccion Asistida ");
modelo13 . agregarCaracteristica("Aire Acondicionado");
Modelo modelo23 = new Modelo ("CLK 500", 2008 , 2);
modelo23 . agregarCaracteristica("Mecanico ");
modelo23 . agregarCaracteristica("Alarma ");
modelo23 . agregarCaracteristica("Air Bag");
modelo23 . agregarCaracteristica(" Alzavidrios Eletricos");
modelo23 . agregarCaracteristica(" Neblineros");
modelo23 . agregarCaracteristica("Llantas ");
modelo23 . agregarCaracteristica(" Direccion Asistida ");
modelo23 . agregarCaracteristica("4x4");
modelo23 . agregarCaracteristica("Radio CD");
modelo23 . agregarCaracteristica("Aire Acondicionado");
marca3 .agregarModelo( modelo13 );
marca3 .agregarModelo( modelo23 );
/** Incremento 2 */
// Mostramos el catalogo completo de cada marca
marca1 .imprimirCatalogo(0);
marca2 .imprimirCatalogo(0);
marca3 .imprimirCatalogo(0);
Usuario .mensajeConsola("");
// Mostramos la cantidad de modelos del anio 2008 que oferta cada marca
Usuario .mensajeConsola("La marca " + marca1 . getNombre() + " tiene "
+ marca1 . autosDelAnio(2008)
+ " modelos anio 2008 en su catalogo .");
Usuario .mensajeConsola("La marca " + marca2 . getNombre() + " tiene "
+ marca2 . autosDelAnio(2008)
+ " modelos anio 2008 en su catalogo .");
Usuario .mensajeConsola("La marca " + marca3 . getNombre() + " tiene "
+ marca3 . autosDelAnio(2008)
+ " modelos anio 2008 en su catalogo .");
/** Incremento 3 */
// Mostramos el catalogo de cada marca solo con los modelos del anio
// preferido
int anio = Usuario .entero (" Ingrese el anio para el que desea revisar los modelos :");
marca1 .imprimirCatalogo(anio );
marca2 .imprimirCatalogo(anio );
marca3 .imprimirCatalogo(anio );
Usuario .mensajeConsola("");
// Ahora mostramos la cantidad de autos que tienen aire acondicionado
Usuario .mensajeConsola("La marca "
+ marca1 .getNombre()
+ " tiene "
+ marca1 . modelosConCaracteristica("Aire acondicionado")
+ " modelos de automoviles con aire acondicionado en su catalogo .");
Usuario .mensajeConsola("La marca "
+ marca2 .getNombre()
+ " tiene "
+ marca2 . modelosConCaracteristica("Aire acondicionado")
+ " modelos de automoviles con aire acondicionado en su catalogo .");
Usuario .mensajeConsola("La marca "
+ marca3 .getNombre()
+ " tiene "
+ marca3 . modelosConCaracteristica("Aire acondicionado")
+ " modelos de automoviles con aire acondicionado en su catalogo .n");
// Finalmente mostramos la cantidad de autos tipo sedan que tienen aire
// acondicionado
Usuario .mensajeConsola("La marca "
+ marca1 .getNombre()
+ " tiene "
+ marca1 . modelosConCaracteristicaPorTipo("Aire acondicionado", 0)
IIC1103 – Cap´ıtulo 5: Strings 42
+ " modelos de automoviles tipo sedan con aire acondicionado en su catalogo .");
Usuario .mensajeConsola("La marca " + marca2 . getNombre() + " tiene " +
marca2 . modelosConCaracteristicaPorTipo("Aire acondicionado", 0)
+ " modelos de automoviles tipo sedan con aire acondicionado en su catalogo .");
Usuario .mensajeConsola("La marca "+ marca3 . getNombre() + " tiene "
+ marca3 . modelosConCaracteristicaPorTipo("Aire acondicionado", 0)
+ " modelos de automoviles tipo sedan con aire acondicionado en su catalogo .");
}
}
Criterios de soluci´on
Clase Modelo
• Atributos: Declaramos los atributos necesarios seg´un nos indican en el enunciado: dos String, uno
para el nombre y otro para las caracter´ısticas y dos enteros, uno para representar el a˜no y otro
para representar el tipo (camioneta, sed´an, etc)
• Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametros
el nombre, el a˜no y el tipo y los asigna a los atributos correspondientes.
• M´etodo agragarCaracteristica: Lo declaramos seg´un el uso mostrado en la clase Principal.
Recibe como par´ametro un String con la caracter´ıstica a agregar y tenemos que concatenarlo al
String que almacena las caracter´ısticas.
• Getters: Seg´un el uso dado en la clase Principal necesitamos 3 m´etodos get para obtener el nombre
del modelo, el a˜no y el tipo.
• M´etodo tieneCaracteristica: Este m´etodo sirve para revisar si el modelo tiene una determinada
caracter´ıstica (para cumplir con lo pedido en el incremento 3), puede hacerse tambi´en s´olo en la
clase Marca. Lo que hacemos es buscar la caracter´ıstica generando todos los substrings desde la
lista de caracter´ısticas que tengan el mismo largo que la caracter´ıstica recibida y comparar hasta
encontrar alguna coincidencia.
• M´etodo mostrar: Revisamos el tipo y seg´un eso mostramos en Consola el nombre del modelo, su
a˜no seguido de ’Sed´an’, ’Station Wagon’ o ’Camioneta’, seg´un corresponda.
Clase Marca:
• Atributos: Declaramos los atributos necesarios seg´un lo que se nos indica en el enunciado: un
String para guardar el nombre y cuatro objetos de la clase Modelo que representen a los modelos
de auto que tiene la Marca.
• Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro
un String con el nombre de la marca y lo asigna al atributo correspondiente.
• M´etodo agregarModelo: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como
par´ametro un objeto de la clase Modelo. Tenemos que revisar a qu´e objeto, de los 4 que tenemos
como atributos, debemos asignarlo, revisando cu´al de ellos es todav´ıa null. Retornamos true o
false seg´un se pudo o no asignar el modelo.
• M´etodo getNombre: Retorna el nombre de la marca.
• M´etodo autosDelAnio: Recorremos todos los modelos y obtenemos su a˜no (cuidando que el objeto
no sea null) y lo comparamos con el a˜no recibido como par´ametro. Retornamos el n´umero de veces
que la comparaci´on fue exitosa.
• M´etodo imprimirCatalogo: Mostramos en la consola el nombre de la marca y el n´umero de autos
del a˜no (seg´un el par´ametro recibido) llamando al m´etodo autosDelAnio. Luego, por cada Modelo
llamamos al m´etodo que muestra su nombre y su tipo.
• M´etodo modelosConCaracteristica: Para no implementar un m´etodo dos veces simplemente
llamamos al m´etodo modelosConCaracteristicaPorTipo definiendo un valor inv´alido para el
tipo.
IIC1103 – Cap´ıtulo 5: Strings 43
• M´etodo modelosConCaracteristicaPorTipo: Recorremos todos los modelos y en cada uno revi-
samos que no sea nulo y que tenga la caracter´ıstica solicitada (llamando al m´etodo que implemen-
tamos en la clase Modelo). Adem´as, en caso que el tipo sea v´alido, tambi´en revisamos que el tipo
del modelo corresponda. Si se cumplen ambas condiciones aumentamos el contador de modelos,
el cual retornamos al finalizar el m´etodo.
Posible soluci´on
import iic1103Package.*;
public class Marca {
// Definimos los atributos necesarios
private String nombre ;
// Definimos los modelos de auto que tiene la Marca
private Modelo modelo0 ;
private Modelo modelo1 ;
private Modelo modelo2 ;
private Modelo modelo3 ;
public Marca(String nombre ) {
this. nombre = nombre ;
}
public Modelo obtenerModelo(int indice ) {
// Obtenemos el modelo segun su indice
if ( indice == 0) {
return modelo0 ;
} else if (indice == 1) {
return modelo1 ;
} else if (indice == 2) {
return modelo2 ;
} else {
return modelo3 ;
}
}
public boolean agregarModelo(Modelo modelo ) {
// Para agregar una nueva marca , buscamos el primero de los atributos
// que aun sea nulo
if ( modelo0 == null) {
modelo0 = modelo ;
} else if (modelo1 == null) {
modelo1 = modelo ;
} else if (modelo2 == null) {
modelo2 = modelo ;
} else if (modelo3 == null) {
modelo3 = modelo ;
} else {
// Si no hay ninguno vacio entonces retornamos false
return false;
}
return true;
}
public int autosDelAnio(int anio) {
// Declaramos una variable para contar , y recorremos los modelos
// buscando aquellos que coincidan con el anio
int contador = 0;
for (int i = 0; i < 4; i++) {
Modelo modelo = obtenerModelo(i);
if (modelo != null && modelo .getAnio () == anio) {
contador ++;
}
}
return contador ;
}
public int modelosConCaracteristica(String caracteristica) {
// Llamamos al metodo que busca tambien por tipo de auto , definiendo un
// valor invalido para dicho parametro
return modelosConCaracteristicaPorTipo( caracteristica , -1);
}
IIC1103 – Cap´ıtulo 5: Strings 44
Strings
Strings
Strings
Strings
Strings
Strings
Strings
Strings
Strings

Más contenido relacionado

La actualidad más candente (20)

13 PHP. Un Ejemplo Con Constantes
13 PHP. Un Ejemplo Con Constantes13 PHP. Un Ejemplo Con Constantes
13 PHP. Un Ejemplo Con Constantes
 
Luis hernandez 22310621
Luis hernandez   22310621Luis hernandez   22310621
Luis hernandez 22310621
 
Cadena de caracteres
Cadena de caracteresCadena de caracteres
Cadena de caracteres
 
Aprendiendo php 2
Aprendiendo php 2Aprendiendo php 2
Aprendiendo php 2
 
Fundamentos de java I
Fundamentos de java IFundamentos de java I
Fundamentos de java I
 
Python básico
Python básicoPython básico
Python básico
 
De Cero A Python En 45 Min
De Cero A Python En 45 MinDe Cero A Python En 45 Min
De Cero A Python En 45 Min
 
31 Php. Cadenas Alfanumericas
31 Php. Cadenas Alfanumericas31 Php. Cadenas Alfanumericas
31 Php. Cadenas Alfanumericas
 
Printf23
Printf23Printf23
Printf23
 
Ejercicios resueltos con Python
Ejercicios resueltos con PythonEjercicios resueltos con Python
Ejercicios resueltos con Python
 
100 1
100 1 100 1
100 1
 
bibliotecas c++
bibliotecas c++bibliotecas c++
bibliotecas c++
 
Ejercicios en Python
Ejercicios en PythonEjercicios en Python
Ejercicios en Python
 
Cadena caracteres
Cadena caracteresCadena caracteres
Cadena caracteres
 
Python (ejercicios)
Python (ejercicios)Python (ejercicios)
Python (ejercicios)
 
Cifrado del cesar
Cifrado del cesarCifrado del cesar
Cifrado del cesar
 
Python03
Python03Python03
Python03
 
Curso de Python
Curso de PythonCurso de Python
Curso de Python
 
Taller I Coreis Python 10112009
Taller I Coreis Python 10112009Taller I Coreis Python 10112009
Taller I Coreis Python 10112009
 
Investigacion 1
Investigacion 1Investigacion 1
Investigacion 1
 

Similar a Strings

Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc X
 
Semana03 prog ii
Semana03 prog iiSemana03 prog ii
Semana03 prog iiPropia
 
Longitud de cadena y funciones en java
Longitud de cadena y funciones en javaLongitud de cadena y funciones en java
Longitud de cadena y funciones en javaRobert Wolf
 
Utp pti_s5_arreglos
 Utp pti_s5_arreglos Utp pti_s5_arreglos
Utp pti_s5_arreglosjcbenitezp
 
Utp pti_s5_arreglos 2012-2
 Utp pti_s5_arreglos 2012-2 Utp pti_s5_arreglos 2012-2
Utp pti_s5_arreglos 2012-2jcbenitezp
 
Lenguaje de Programacion - Java
Lenguaje de Programacion - JavaLenguaje de Programacion - Java
Lenguaje de Programacion - Javazousbabastre
 
Implementacion de punteros
Implementacion de punterosImplementacion de punteros
Implementacion de punterosKareliaRivas
 
Java - Sintaxis Básica 2015
Java - Sintaxis Básica 2015Java - Sintaxis Básica 2015
Java - Sintaxis Básica 2015Renny Batista
 
Introducción a la programación y la informática. Tema 6
Introducción a la programación y la informática. Tema 6Introducción a la programación y la informática. Tema 6
Introducción a la programación y la informática. Tema 6Andres Garcia Garcia
 
Utp lpi_s5_arreglos 2012-2
 Utp lpi_s5_arreglos 2012-2 Utp lpi_s5_arreglos 2012-2
Utp lpi_s5_arreglos 2012-2jcbenitezp
 
Estructura sintactica de los lenguajes de programacion
Estructura sintactica de los lenguajes de programacionEstructura sintactica de los lenguajes de programacion
Estructura sintactica de los lenguajes de programacionandreinagracielarojasadam
 
Clase10 stringsio
Clase10 stringsioClase10 stringsio
Clase10 stringsiojorg_marq
 
SCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/OSCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/Oflekoso
 
Java script teoria
Java script teoriaJava script teoria
Java script teoriassxdan
 

Similar a Strings (20)

Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase string
 
Semana03 prog ii
Semana03 prog iiSemana03 prog ii
Semana03 prog ii
 
Poo4
Poo4Poo4
Poo4
 
Longitud de cadena y funciones en java
Longitud de cadena y funciones en javaLongitud de cadena y funciones en java
Longitud de cadena y funciones en java
 
Utp pti_s5_arreglos
 Utp pti_s5_arreglos Utp pti_s5_arreglos
Utp pti_s5_arreglos
 
Utp pti_s5_arreglos 2012-2
 Utp pti_s5_arreglos 2012-2 Utp pti_s5_arreglos 2012-2
Utp pti_s5_arreglos 2012-2
 
Lenguaje de Programacion - Java
Lenguaje de Programacion - JavaLenguaje de Programacion - Java
Lenguaje de Programacion - Java
 
Implementacion de punteros
Implementacion de punterosImplementacion de punteros
Implementacion de punteros
 
Java - Sintaxis Básica 2015
Java - Sintaxis Básica 2015Java - Sintaxis Básica 2015
Java - Sintaxis Básica 2015
 
Introducción a la programación y la informática. Tema 6
Introducción a la programación y la informática. Tema 6Introducción a la programación y la informática. Tema 6
Introducción a la programación y la informática. Tema 6
 
Utp lpi_s5_arreglos 2012-2
 Utp lpi_s5_arreglos 2012-2 Utp lpi_s5_arreglos 2012-2
Utp lpi_s5_arreglos 2012-2
 
Estructura sintactica de los lenguajes de programacion
Estructura sintactica de los lenguajes de programacionEstructura sintactica de los lenguajes de programacion
Estructura sintactica de los lenguajes de programacion
 
Clase10 stringsio
Clase10 stringsioClase10 stringsio
Clase10 stringsio
 
Implementación de Aplicaciones Basadas en Texto
Implementación de Aplicaciones Basadas en TextoImplementación de Aplicaciones Basadas en Texto
Implementación de Aplicaciones Basadas en Texto
 
Clase 10 expresiones regulares
Clase 10 expresiones regularesClase 10 expresiones regulares
Clase 10 expresiones regulares
 
Arreglos
ArreglosArreglos
Arreglos
 
!Prograc8
!Prograc8!Prograc8
!Prograc8
 
TutorialKotlin.docx
TutorialKotlin.docxTutorialKotlin.docx
TutorialKotlin.docx
 
SCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/OSCJP, Clase 10: Strings, I/O
SCJP, Clase 10: Strings, I/O
 
Java script teoria
Java script teoriaJava script teoria
Java script teoria
 

Más de Robert Wolf

Tema 16 acceso a base de datos usando jpa por gio
Tema 16   acceso a base de datos usando jpa por gioTema 16   acceso a base de datos usando jpa por gio
Tema 16 acceso a base de datos usando jpa por gioRobert Wolf
 
Tema 15 aplicaciones de dos capas por gio
Tema 15   aplicaciones de dos capas por gioTema 15   aplicaciones de dos capas por gio
Tema 15 aplicaciones de dos capas por gioRobert Wolf
 
Tema 14 imágenes en java por gio
Tema 14   imágenes en java por gioTema 14   imágenes en java por gio
Tema 14 imágenes en java por gioRobert Wolf
 
Tema 13 gráficas en java por gio
Tema 13   gráficas en java por gioTema 13   gráficas en java por gio
Tema 13 gráficas en java por gioRobert Wolf
 
Tema 12 hilos en java por gio
Tema 12   hilos en java por gioTema 12   hilos en java por gio
Tema 12 hilos en java por gioRobert Wolf
 
Tema 11 expresiones regulares en java por gio
Tema 11   expresiones regulares en java por gioTema 11   expresiones regulares en java por gio
Tema 11 expresiones regulares en java por gioRobert Wolf
 
Tema 10 clase abstractas e interfaz
Tema 10 clase abstractas e interfazTema 10 clase abstractas e interfaz
Tema 10 clase abstractas e interfazRobert Wolf
 
Tema 10 entrada y salida por gio
Tema 10   entrada y salida por gioTema 10   entrada y salida por gio
Tema 10 entrada y salida por gioRobert Wolf
 
Tema 9 pruebas unitarias por gio
Tema 9   pruebas unitarias por gioTema 9   pruebas unitarias por gio
Tema 9 pruebas unitarias por gioRobert Wolf
 
Tema 9 aplicaciones de dos capas por gio
Tema 9   aplicaciones de dos capas por gioTema 9   aplicaciones de dos capas por gio
Tema 9 aplicaciones de dos capas por gioRobert Wolf
 
Tema 8 entrada y salida por gio
Tema 8   entrada y salida por gioTema 8   entrada y salida por gio
Tema 8 entrada y salida por gioRobert Wolf
 
Tema 8 desarrollo de aplicaciones en java por gio
Tema 8   desarrollo de aplicaciones en java por gioTema 8   desarrollo de aplicaciones en java por gio
Tema 8 desarrollo de aplicaciones en java por gioRobert Wolf
 
Tema 7 gui, swing y java beans por gio
Tema 7   gui, swing y java beans por gioTema 7   gui, swing y java beans por gio
Tema 7 gui, swing y java beans por gioRobert Wolf
 
Tema 7 desarrollo de aplicaciones en java - lsia por gio
Tema 7   desarrollo de aplicaciones en java - lsia por gioTema 7   desarrollo de aplicaciones en java - lsia por gio
Tema 7 desarrollo de aplicaciones en java - lsia por gioRobert Wolf
 
Tema 6 gui, swing y java beans por gio
Tema 6   gui, swing y java beans por gioTema 6   gui, swing y java beans por gio
Tema 6 gui, swing y java beans por gioRobert Wolf
 
Tema 6 colecciones por gio
Tema 6   colecciones por gioTema 6   colecciones por gio
Tema 6 colecciones por gioRobert Wolf
 
Tema 5 arreglos y cadenas por gio
Tema 5   arreglos y cadenas por gioTema 5   arreglos y cadenas por gio
Tema 5 arreglos y cadenas por gioRobert Wolf
 

Más de Robert Wolf (20)

Tema6resumido
Tema6resumidoTema6resumido
Tema6resumido
 
Tema4 herencia
Tema4 herenciaTema4 herencia
Tema4 herencia
 
Tema 6
Tema 6Tema 6
Tema 6
 
Tema 16 acceso a base de datos usando jpa por gio
Tema 16   acceso a base de datos usando jpa por gioTema 16   acceso a base de datos usando jpa por gio
Tema 16 acceso a base de datos usando jpa por gio
 
Tema 15 aplicaciones de dos capas por gio
Tema 15   aplicaciones de dos capas por gioTema 15   aplicaciones de dos capas por gio
Tema 15 aplicaciones de dos capas por gio
 
Tema 14 imágenes en java por gio
Tema 14   imágenes en java por gioTema 14   imágenes en java por gio
Tema 14 imágenes en java por gio
 
Tema 13 gráficas en java por gio
Tema 13   gráficas en java por gioTema 13   gráficas en java por gio
Tema 13 gráficas en java por gio
 
Tema 12 hilos en java por gio
Tema 12   hilos en java por gioTema 12   hilos en java por gio
Tema 12 hilos en java por gio
 
Tema 11 expresiones regulares en java por gio
Tema 11   expresiones regulares en java por gioTema 11   expresiones regulares en java por gio
Tema 11 expresiones regulares en java por gio
 
Tema 10 clase abstractas e interfaz
Tema 10 clase abstractas e interfazTema 10 clase abstractas e interfaz
Tema 10 clase abstractas e interfaz
 
Tema 10 entrada y salida por gio
Tema 10   entrada y salida por gioTema 10   entrada y salida por gio
Tema 10 entrada y salida por gio
 
Tema 9 pruebas unitarias por gio
Tema 9   pruebas unitarias por gioTema 9   pruebas unitarias por gio
Tema 9 pruebas unitarias por gio
 
Tema 9 aplicaciones de dos capas por gio
Tema 9   aplicaciones de dos capas por gioTema 9   aplicaciones de dos capas por gio
Tema 9 aplicaciones de dos capas por gio
 
Tema 8 entrada y salida por gio
Tema 8   entrada y salida por gioTema 8   entrada y salida por gio
Tema 8 entrada y salida por gio
 
Tema 8 desarrollo de aplicaciones en java por gio
Tema 8   desarrollo de aplicaciones en java por gioTema 8   desarrollo de aplicaciones en java por gio
Tema 8 desarrollo de aplicaciones en java por gio
 
Tema 7 gui, swing y java beans por gio
Tema 7   gui, swing y java beans por gioTema 7   gui, swing y java beans por gio
Tema 7 gui, swing y java beans por gio
 
Tema 7 desarrollo de aplicaciones en java - lsia por gio
Tema 7   desarrollo de aplicaciones en java - lsia por gioTema 7   desarrollo de aplicaciones en java - lsia por gio
Tema 7 desarrollo de aplicaciones en java - lsia por gio
 
Tema 6 gui, swing y java beans por gio
Tema 6   gui, swing y java beans por gioTema 6   gui, swing y java beans por gio
Tema 6 gui, swing y java beans por gio
 
Tema 6 colecciones por gio
Tema 6   colecciones por gioTema 6   colecciones por gio
Tema 6 colecciones por gio
 
Tema 5 arreglos y cadenas por gio
Tema 5   arreglos y cadenas por gioTema 5   arreglos y cadenas por gio
Tema 5 arreglos y cadenas por gio
 

Strings

  • 1. Pontificia Universidad Cat´olica de Chile Escuela de Ingenier´ıa Departamento de Ciencia de la Computaci´on IIC1103 — Introducci´on a la Programaci´on Cap´ıtulo 5: Strings Resumen te´orico Los Strings son una secuencia de caracteres, incluyendo letras (may´usculas y min´usculas), signos, espacios, caracteres especiales, etc. En palabras simples, los Strings sirven para guardar palabras, oraciones, etc. En java los Strings son objetos, tipo String. Al momento de crearlos, la manera m´as sencilla es: String hola = "Hello World"; Los Strings, al ser objetos, tambi´en pueden ser inicializados como tales, a trav´es del constructor: String s = new String(); // String vacio String s = new String("Hola"); // String "Hola" M´etodos de la clase String La clase String tiene una gran variedad de m´etodos ´utiles. La lista completa puede encontrarse en la documen- taci´on oficial (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html). A continuaci´on explicamos los m´etodos que m´as se utilizan en este curso. int length() Sencillamente, retorna el largo (la cantidad de caracteres) de un String. String texto1 = "Hola"; String texto2 = "(/.,;>.)"; String texto3 = ""; String texto4 = " "; int n = texto1.length(); // 4 int m = texto2.length(); // 8 int p = texto3.length(); // 0 int q = texto4.length(); // 1 char charAt(int index) Retorna el caracter que se encuentra en la posici´on dada por index. Si index es mayor o igual que el largo del String, el programa se caer´a al ejecutar, aunque Eclipse no le avisar´a al respecto (no es capaz de prever dicho comportamiento), y al compilar tampoco habr´a errores. Por esta raz´on, cada vez que utilice este m´etodo debe primero revisar el largo del String. String texto = "¡Hola Juanito!"; char c1 = texto.charAt(0); // ’¡’ char c2 = texto.charAt(1); // ’H’ char c3 = texto.charAt(13); // ’!’ char c4 = texto.charAt(20); // error char c5 = texto.charAt( texto.length() - 1 ); // ’!’ IIC1103 – Cap´ıtulo 5: Strings 1
  • 2. Ejemplo de c´omo evitar errores: String texto = Usuario.texto("Ingrese un texto:"); char c; if(texto.length() > 20) { c = texto.charAt(20); //... } else { Usuario.mensaje("String"); } boolean startsWith(String s) Devuelve true si el String comienza con el String s entregado como par´ametro. La coincidencia debe ser exacta (se distingue may´usculas de min´usculas, por ejemplo, y los caracteres con tilde no son iguales a los que no lo llevan). String texto = "¡Hola Juanito!"; boolean b1 = texto.startsWith("¡"); // true boolean b2 = texto.startsWith("¡Hola ") // true boolean b3 = texto.startsWith("¡hola Juanito!") // false boolean b4 = texto.startsWith("¡Hola Juanito! ") // false boolean b5 = texto.startsWith("¡Hola Juanito!") // true boolean startsWith(String s, int k) Como el m´etodo anterior, pero comienza a revisar desde el ´ındice (posici´on) k, sin importar lo que haya antes. Si k == 0, entonces el m´etodo es equivalente al anterior. String texto = "¡Hola Juanito!"; boolean b1 = texto.startsWith("Hola", 1); // true boolean b2 = texto.startsWith(" Juanito!", 5); // true boolean b3 = texto.startsWith("a", 7); // false boolean b4 = texto.startsWith("¡", 20); // false int indexOf(char c) Devuelve un entero que indica la posici´on donde aparece por primera vez el caracter c. Si el caracter no aparece en todo el String, devuelve -1. String texto = "¡Hola Juanito!"; int n = texto.indexOf(’o’); // 2 int m = texto.indexOf(’ ’); // 5 int p = texto.indexOf(’¡’); // 0 int q = texto.indexOf(’z’); // -1 int indexOf(String s) Similar al anterior, s´olo que devuelve la posici´on donde aparece por primera vez un determinado String. String texto = "En la arboleda un arbolito"; int n = texto.indexOf("arbol"); // 6 int m = texto.indexOf("´arbol"); // -1 int p = texto.indexOf("boli"); // 20 int q = texto.indexOf("bol"); // 8 IIC1103 – Cap´ıtulo 5: Strings 2
  • 3. int indexOf(char c, int fromIndex) y int indexOf(String s, int fromIndex) Como el m´etodo indexOf(String s), pero comienza a buscar desde la posici´on fromIndex. int lastIndexOf(char c), int lastIndexOf(String s), int lastIndexOf(char c, int fromIndex), int lastIndexOf(String s, int fromIndex) Como indexOf(char c), pero en vez de buscar la primera aparici´on del char c, busca la ´ultima. Retorna -1 si no lo encuentra. Se definen de manera an´aloga a los anteriores: boolean equals(String s) Retorna true cuando ambos String son exactamente iguales. Esto quiere decir que el largo de ambos es el mismo, y que en cada posici´on encontramos el mismo caracter. String texto1 = "casa"; String texto2 = "caza"; String texto3 = "casi"; String texto4 = "casa"; String texto5 = "CaSa"; boolean b1 = texto1.equals(texto3); // false boolean b2 = texto4.equals(texto1); // true boolean b3 = texto3.equals(texto1); // false boolean b4 = texto1.equals(texto5); // false boolean equalsIgnoreCase(String s) Retorna true cuando ambos String son iguales, sin importar may´usculas y min´usculas. String texto1 = "casa"; String texto2 = "caza"; String texto3 = "casi"; String texto4 = "casa"; String texto5 = "CaSa"; boolean b1 = texto1.equalsIgnoreCase(texto3); // false boolean b2 = texto4.equalsIgnoreCase(texto1); // true boolean b3 = texto3.equalsIgnoreCase(texto1); // false boolean b4 = texto1.equalsIgnoreCase(texto5); // true int compareTo(String s) Este m´etodo compara lexicogr´aficamente dos String. Parte en el primer par de caracteres hasta encontrar un par de char distintos. Si encuentra dos caracteres distintos, retorna la diferencia entre ellos (recuerde que char funciona como un n´umero entero). Si uno de los String comienza con el otro, retorna el n´umero de caracteres adicionales que tiene. Si ambos String son iguales, retorna 0. String texto = "radiograf´ıa"; int n = texto.compareTo("radio"); // 6 int m = texto.compareTo("radiolog´ıa"); // -5 int p = texto.compareTo("rabia"); // 2 int q = texto.compareTo("ralentizar"); // -8 int r = texto.compareTo("radiografia"); // 132 int s = texto.compareTo("radiograf´ıa"); // 0 IIC1103 – Cap´ıtulo 5: Strings 3
  • 4. String substring(int inicio, int fin) Retorna una parte del String: desde la posici´on inicio hasta la posici´on fin. String texto = "desenfreno"; String subTexto = texto.substring(5, 10); // "freno" String replaceAll(String aReemplazar , String reemplazo) Reemplaza todas las ocurrencias de aReemplazar por reemplazo. String t1 = "El auto volaba r´apido"; String t2 = t1.replaceAll("auto", "avi´on")); // "El avi´on volaba r´apido" IIC1103 – Cap´ıtulo 5: Strings 4
  • 5. Los Strings soportan todos los caracteres de la tabla ASCII: Fuente de referencia: http://users.physik.fu-berlin.de/~goerz/blog/wp-content/uploads/2008/09/ascii.gif Para utilizarlos se puede “castear” un n´umero entero (la representaci´on decimal del caracter seg´un la tabla ASCII) a un “char”. char c = (char) 36; // signo pesos Adem´as se pueden utilizar ciertos caracteres especiales, anteponiendo : Descripci´on Representaci´on Barra invertida Tabulaci´on horizontal t Salto de L´ınea n Comillas simples ’ Comillas dobles " IIC1103 – Cap´ıtulo 5: Strings 5
  • 6. Ejemplos Problema 1: Varios Enunciado Escriba m´etodos en Java que: Rote una palabra, por ejemplo “auto” queda “otua”. Ocupe una palabra para crear un pal´ındrome, por ejemplo “auto” queda “autotua”. Busque una palabra dentro de un texto y la marque con un “ ”, por ejemplo “auto” en “Habian muchos autos” queda “Habian muchos autos”. Cuente la cantidad de ocurrencias de una palabra en un texto, por ejemplo “hola” en “El gato decia hola muchas veces al dia, hola”, retorna 2. Criterios de soluci´on Para rotar la palabra basta con crear un nuevo String (nueva variable) e ir concaten´andole las le- tras de nuestro String original, pero recorriendo el original desde atr´as hacia adelante (for por su largo/length). Muy similar al anterior, se puede hacer de dos maneras. Se le puede concatenar el string obtenido con el m´etodo anterior o se puede hacer de manera manual. Para encontrar donde aparece la palabra es claro que hay que ocupar indexOf. Para agregar el “ ” la mejor manera es guardar la posici´on donde est´a la palabra buscada y ocuparla para separar la oraci´on en dos substrings, uno con todos los caracteres a la izquierda de la posici´on y otro a la derecha. Luego concatenamos el subtring de la izquierda con un “ ” y el substring de la derecha. Para contar la cantidad de veces que aparece la palabra ocupamos indexOf para ver si est´a, si la posici´on es distinta de -1 sumamos uno a la cantidad de veces que encontramos la palabra. Es importante cambiar la posici´on desde la que buscamos en nuestro String ya que, o si no, podemos contar infinitas veces la misma palabra. IIC1103 – Cap´ıtulo 5: Strings 6
  • 7. Posible soluci´on import iic1103Package.*; public class Principal { public static String palindromizar(String palindrome) { // obtengo el largo de la palabra enviada int largo = palindrome. length (); // iteramos hasta el largo menos 2 for (int i = largo - 2; i >= 0; i--) { // le agregamos la ultima letra palindrome = palindrome + palindrome.charAt (i); } return palindrome; // retorno el palindrome } public static String darVuelta(String palabra ) { // aqui guardamos el resultado String palabraRotada = ""; // parto desde el final y termino en el principio for (int i = palabra . length () - 1; i >= 0; i--) { // le voy agregando los caracteres palabraRotada = palabraRotada + palabra . charAt (i); } // retorno la palabra rotada return palabraRotada; } public static int buscarCantidad(String palabra , String textoAUsar) { // Contamos cuantas veces esta la palabra int veces = 0; int pos = 0; while (pos != -1) { // Buscamos string y contamos , buscamos desde pos+1 para no volver a // leer la misma palabra pos = textoAUsar. indexOf (palabra , pos + 1); // si pos es distinta de -1 contamos una vez mas if (pos != -1) { veces ++; } } return veces; } public static boolean buscarPalabra(String palabra , String textoAUsar) { // Busca la palabra int pos = textoAUsar. indexOf (palabra ); if (pos != -1) { // Agregamos "_" String textoAMostrar = textoAUsar. substring(0, pos) + "_" + textoAUsar. substring(pos); Usuario .mensajeConsola( textoAMostrar); return true; } else { Usuario .mensajeConsola("No fue encontrado el string " + palabra + " en el texto "); return false; } } public static void main(String [] args) { String nombre = "auto"; Usuario .mensajeConsola( palindromizar(nombre )); Usuario .mensajeConsola( darVuelta(nombre )); buscarPalabra("hola", "El gato decia hola muchas veces al dia , hola"); } } IIC1103 – Cap´ıtulo 5: Strings 7
  • 8. Problema 2: Clase String Enunciado Un desarrollador est´a construyendo la clase String de Java, pero a medio camino deja el tema botado y se va del pa´ıs. Sin poder contactarlo, le piden a usted completar la clase, sabiendo que la representaci´on interna, constructores y operadores ya existen, y se encuentran ya disponibles los siguientes m´etodos: char charAt(int index) Retorna el caracter en la posici´on index. int compareTo(String another) Compara dos strings lexicogr´aficamente. int length() Retorna el largo del string. Para poder arreglar este dilema, le piden a usted desarrollar los siguientes m´etodos (utilizando s´olo lo ya construido): String substring(int begin, int end) Retorna el substring que va desde la posici´on begin a la posici´on end, inclusive. Devuelve null si existe alg´un problema con los ´ındices recibidos. String toUpperCase() Retorna un string equivalente al actual, pero con todas las letras convertidas a may´usculas. Ignore caracteres que no pertenezcan al alfabeto ingl´es. static valueOf(int i) Retorna el string que representa al entero i. int indexOf(String str, int from) Retorna el ´ındice en que se encuentra el string str en el string actual, o -1 si es que no se encuentra (o cualquier otro problema). S´olo encuentra str a a partir del ´ındice from. Criterios de soluci´on M´etodo substring: Lo primero que debemos hacer es revisar que los par´ametros recibidos correspondan a ´ındices v´alidos seg´un el largo del String. Si el inicio es menor que cero y el fin mayor que el largo del String -1 entonces retornamos false. Si no, para obtener un substring, debemos implementar un ciclo (for por ejemplo) que recorra el String completo, desde el inicio hasta el fin recibidos como par´ametros, y vaya obteniendo cada char con el m´etodo charAt y lo vaya concatenando, formando as´ı el substring a retornar. M´etodo toUpperCase: Para cambiar las letras a may´uscula debemos implementar un ciclo que recorra todo el String obteniendo cada uno de sus caracteres con el m´etodo charAt. Luego revisamos cada caracter si es que est´a en min´uscula, para esto basta con comparar si se encuentra en el rango de ’a’ a ’z’ (recordando que los caracteres est´an ordenados en la tabla ASCII). Si est´a en min´uscula lo que tenemos que hacer es al inicio de las may´usculas ’A’ sumarle la distancia del caracter en min´uscula al inicio de las min´usculas ’a’. As´ı, tendremos el mismo caracter pero ahora en may´uscula. M´etodo valueOf: Para pasar el valor entero a String tenemos que revisar primero si el n´umero es negativo o positivo. Si el n´umero es negativo tenemos que agregar un gui´on ’-’ al String resultante. Luego recorremos el n´umero y vamos obteniendo cada uno de sus d´ıgitos (dividiendo el n´umero por 10 y obteniendo el resto) y para cada d´ıgito obtenemos el char que corresponde y lo concatenamos al String que representa el resultado de pasar el n´umero a String. M´etodo indexOf: En este m´etodo lo que tenemos que hacer es recorrer todo el String, partiendo desde el inicio ingresado por el usuario. Dentro del ciclo debemos revisar el String ingresado como par´ametro (el buscado) para revisar cada uno de sus caracteres y compararlos con el String original. As´ı si todos los caracteres coinciden devolvemos la posici´on donde encontramos el primer caracter que fue igual. IIC1103 – Cap´ıtulo 5: Strings 8
  • 9. Posible soluci´on /** * Retorna el substring que va desde la posicion begin a la posicion end , * inclusive. Devuelve null si existe algun problema con los indices * recibido . */ public String substring(int begin , int end) { if ( begin < 0 || end > length () - 1) return null; String res = ""; for (int i = begin; i <= end; i++) res += charAt (i); return res; } /** * Retorna un string equivalente al actual , pero con todas las letras * convertidas a mayuscula. Ignora caracteres que no pertenezcan al alfabeto * ingles */ public String toUpperCase() { String res = ""; for (int i = 0; i < length (); i++) { char aux = charAt (i); if (’a’ <= aux && aux <= ’z’) res += (char) (aux + ’A’ - ’a’); else res += aux; } return res; } /** * Retorna el string que representa al entero i. */ public static String valueOf (int i) { if (i == 0) return "0"; boolean negative = false; if (i < 0) { negative = true; i = -i; } String res = ""; while (i > 0) { res = " " + (char) (i % 10 + ’0’) + res; i /= 10; } if ( negative ) res = "-" + res; return res; } /** * Retorna el indice en que se encuentra el string str en el string actual , * o -1 si es que no se encuentra (o cualquier otro problema ). Solo * encuentra str a a partir del indice from. */ public int indexOf (String str , int from) { for (int i = from; i < length (); i++) { for (int j = 0; (i + j < length ()) && charAt (i + j) == str.charAt (j); j++) { if (j == str.length () - 1) return i; } } return -1; } IIC1103 – Cap´ıtulo 5: Strings 9
  • 10. Problema 3: Iniciando un Juego Enunciado Debemos crear un algoritmo que permita inicializar un juego. Para ello debe pedir un texto al usuario en que se indiquen los datos necesarios. La primera palabra de este texto representar´a el modo en el cual se va a jugar, pudiendo ser MULTI, PC o DEMO. Luego viene un signo punto y coma (;) seguido por los nombres de los jugadores que intervendr´an en el juego separados entre ellos por un gui´on (-). En caso de ser en modo PC solamente viene el nombre de un jugador, en cambio si es modo MULTI pueden venir entre 2 y 4 nombres. Los siguientes son un ejemplo del texto que se ingresa: MULTI;Marcos-Karen-Marcelo-Rosa PC;Marcos Para el primer texto su programa debiera iniciarse en modo Multi usuario para cuatro jugadores, con los nombres ah´ı descritos. En caso de ingresarse el segundo texto, su programa debiera inicializarse en modo versus PC, con un ´unico usuario llamado Marcos. Criterios de soluci´on Se nos pide reconocer un texto ingresado por el usuario. Como datos nos dan que los separadores son “;” y “-”, para ello nuestro programa tiene que ser capaz de buscar el car´acter “;” (charAt()), en una primera instancia para poder realizar la separaci´on. Luego se nos pide verificar que la primera parte corresponda a “MULTI”, “PC” o “DEMO” (validaci´on con equals). Con la segunda parte de esta divisi´on hacemos lo mismo que al principio y separamos por “-”, verificando que la cantidad de jugadores ingresados corresponda a la se˜nalada seg´un el enunciado. Posible soluci´on import iic1103Package.*; public class Principal { public static void main(String [] args) { while (true) { String x = Usuario .texto ("Ingrese el mensaje a validar "); if (Validador(x)) break ; } } // Metodo que valida el texto que es ingresado static boolean Validador(String validar ) { int donde = validar . indexOf (";"); // buscamos el separador ";" if ( donde == -1 && ! validar .equalsIgnoreCase("DEMO")) { Usuario .mensaje ("No es un formato valido "); return false; } else if (validar . equalsIgnoreCase("DEMO")) { // Notamos el tipo DEMO Usuario .mensaje ("Tipo de juego: DEMO"); return true; } String parte1 = validar . substring(0, donde ); String parte2 = validar . substring(donde + 1); String mensaje = ""; // Buscamos la contidad de jugadores int jugadores = cantidad_jugadores(parte2 ); if ( jugadores > 4) { // No pueden existir mas de 4 jugadores: Usuario .mensaje ("No es un formato valido : Ingreso mas de 4 jugadores"); return false; } IIC1103 – Cap´ıtulo 5: Strings 10
  • 11. if ( parte1 . equalsIgnoreCase("PC")) { if (jugadores == 0) { // El tipo PC requiere minimo 1 jugador Usuario .mensaje ("No es un formato valido : No especifico jugadores para Pc"); return false; } mensaje = "Tipo de juego: PC" + ’n’ + jugadores(parte2 ); } else if (parte1 . equalsIgnoreCase("MULTI")) { if (jugadores < 2) { // El tipo MULTI requiere minimo 2 jugadores Usuario .mensaje ("No es un formato valido : no ingreso suficientes jugadores para el tipo Multi"); return false; } mensaje = "Tipo de juego: MULTI" + ’n’ + jugadores(parte2 ); } else { Usuario .mensaje ("No es un formato valido "); return false; } Usuario .mensaje (mensaje ); return true; } // Metodo que Determina la cantidad de jugadores existentes static int cantidad_jugadores(String jugadores) { if ( jugadores.length () == 0) { return 0; } int cantidad = 1; for (int i = 0; i < jugadores.length (); i++) { if (jugadores.charAt (i) == ’-’) { cantidad ++; } } return cantidad ; } // Metodo que retorna El mensaje correspondiente de los jugadores static String jugadores(String parte2 ) { String mensaje = "Jugador 1: "; int y = 1; for (int k = 0; k < parte2 .length (); k++) { if (parte2 .charAt (k) == ’-’) { // Encontro un ’-’... asi que se salta al siguiente jugador y++; mensaje += "nJugador " + y + ": "; } else { mensaje += parte2 . charAt (k); } } return mensaje ; } } IIC1103 – Cap´ıtulo 5: Strings 11
  • 12. Problema 4: Double Enunciado Haga un c´odigo que permita determinar si un texto ingresado es un double, independiente que el n´umero este separado con: ’.’ o ’,’. De ´esta forma podemos usar seguros el m´etodo Double.ParseDouble(String str);. Criterios de soluci´on Observamos que ´esta es una validaci´on simple, s´olo debemos verificar que los caracteres sean n´umeros, signo negativo, o separadores v´alidos, adem´as de que s´olo exista un separador. Adicionalmente podemos hacer el m´etodo que transforme las comas en puntos, para que Java pueda manejar el n´umero. Posible soluci´on import iic1103Package.*; public class Principal { public static void main(String [] args) { while (true) { String x = Usuario .texto ("Ingrese el decimal a validar "); if (esDouble (x)) { x = remplazar(x); double numero = Double .parseDouble(x); Usuario .mensaje ("El numero ingresado es: " + numero ); break ; } } } // Metodo que valida si un numero es decimal static boolean esDouble (String aComprobar) { if ( aComprobar.length () == 0) { // Si es vacio no sera un double return false; } int comas = 0; if (!(48 <= (int) aComprobar.charAt (0) && (int) aComprobar.charAt (0) <= 57) && !(( int) aComprobar.charAt (0) == 44 || (int) aComprobar .charAt (0) == 46) && (int) aComprobar.charAt (0) != 45) { return false; // Si no es un numero , ni un separador ni un signo // ’-’... no es un double } for (int i = 1; i < aComprobar.length (); i++) { boolean esnumero = 48 <= (int) aComprobar. charAt (i) && (int) aComprobar.charAt (i) <= 57; boolean escoma = (int) aComprobar.charAt (i) == 44 || (int) aComprobar.charAt (i) == 46; if (! esnumero && !escoma ) { return false; } else if (aComprobar. charAt (i) == 44 || aComprobar.charAt (i) == 46) { comas ++; if (comas > 1) return false; } } Usuario .mensaje ("Es un double "); return true; } // Metodo que reemplaza la primera ’,’ por ’.’ static String remplazar(String s) { int donde = s.indexOf (","); if(donde != -1) { return (s.substring(0, donde) + ’.’ + s. substring(donde + 1)); }else{ return s; } } } IIC1103 – Cap´ıtulo 5: Strings 12
  • 13. Problema 5: Operaciones Enunciado Realice un m´etodo que reciba un String con una operaci´on b´asica (+, −, ∗, /) y devuelve el resultado de esa operaci´on. Por ejemplo si recibe 4,5 + 35 debe devolver 39,5. Para esto puede ocupar s´olo los siguientes m´etodos de la clase String: charAt, length Criterios de soluci´on Lo primero que debemos hacer es identificar cu´al es la operaci´on que se encuentra en el String. Para esto utilizamos un ciclo (un for por ejemplo), para recorrer todo el String e ir obteniendo cada uno de los caracteres con el m´etodo charAt. Cada caracter lo comparamos con una de las posibles operaciones. Al encontrar la operaci´on guardamos el caracter y tambi´en la posici´on donde la encontramos para luego obtener los n´umeros que vienen en el String. Para recuperar los n´umeros del String, como s´olo podemos utilizar el m´etodo charAt, lo que hacemos son dos ciclos, uno que recorra la primera parte del string obteniendo cada uno de los caracteres y concaten´andolos en un nuevo String que represente el primer n´umero, y el segundo ciclo que haga lo mismo pero con la segunda parte del String. Luego transformamos los Strings que representan a los n´umeros en variables de tipo double y revisando la operaci´on encontrada retornamos el resultado de la operaci´on. Posible soluci´on public double Operacion(String op) { // Debemos identificar cual es la operacion que se encuentra en el String char opDada = 0; int posOp = 0; for (int i = 0; i < op. length (); i++) { if (op.charAt (i) == ’+’ || op.charAt (i) == ’-’ || op.charAt (i) == ’*’ || op.charAt (i) == ’/’) { opDada = op.charAt (i); posOp = i; break ; } } // Ahora debemos identificar los valores involucrados double valor1 = 0, valor2 = 0; String aux = ""; for (int i = 0; i < posOp ; i++) { aux += op.charAt (i); } valor1 = Double . parseDouble(aux); aux = ""; for (int i = posOp + 1; i < op.length (); i++) { aux += op.charAt (i); } valor2 = Double . parseDouble(aux); if ( opDada == ’+’) { return valor1 + valor2 ; } else if (opDada == ’-’) { return valor1 - valor2 ; } else if (opDada == ’*’) { return valor1 * valor2 ; } else { return valor1 / valor2 ; } } IIC1103 – Cap´ıtulo 5: Strings 13
  • 14. Problema 6: Palabra Abecedaria Enunciado Una palabra se dice abecedaria si las letras que la forman se encuentran en orden alfab´etico si son le´ıdas de izquierda a derecha. Por ejemplo, las siguientes palabras cumplen con ser abecedarias: Amor, filo, chintz, luz, dinos. Escriba un m´etodo que permita determinar si una palabra es abecedaria. El m´etodo debe recibir un string como par´ametro y retornar verdadero en caso que la palabra sea abecedaria, y falso en caso contrario. Para esto puede ocupar s´olo los siguientes m´etodos de la clase String: charAt, length, equals, compareTo Criterios de soluci´on Para revisar si la palabra es abecedaria tenemos que ir revisando cada uno de los caracteres y ver que ninguno sea mayor (lexicogr´aficamente) que el siguiente. Para eso lo mejor es utilizar un ciclo, un for por ejemplo, para recorrer la palabra entera, caracter por caracter. Utilizando el m´etodo charAt obtenemos el caracter actual y el siguiente y comparamos si el actual es mayor que el siguiente. Si esto ocurre retornamos false, de lo contrario seguimos revisando el resto de la palabra. Adem´as de esto tenemos que considerar que pueden haber caracteres en may´uscula, los cuales para que lo anterior funcione debemos pasarlos a min´uscula. Para esto simplemente le restamos el inicio de las letras may´usculas (’A’) y le sumamos el inicio de las letras min´usculas (’a’). Posible soluci´on public class Palabra { public boolean abecedaria(String palabra ) { for (int i = 0; i < palabra .length () - 1; i++) { char primeraLetra = palabra .charAt (i); char segundaLetra = palabra .charAt (i + 1); if (primeraLetra >= ’A’ && primeraLetra <= ’Z’) primeraLetra = (char) (( int) primeraLetra - (int) ’A’ + (int) ’a’); if (segundaLetra >= ’A’ && segundaLetra <= ’Z’) segundaLetra = (char) (( int) segundaLetra - (int) ’A’ + (int) ’a’); if (primeraLetra > segundaLetra) return false; } return true; } } IIC1103 – Cap´ıtulo 5: Strings 14
  • 15. Problema 7: Combinaci´on Enunciado Implemente una clase llamada Combinacion, la cual recibe dos String en el constructor. Su clase debe tener un m´etodo que reciba un char y retorne la cantidad de apariciones de ese char en ambos textos. Un m´etodo que retorne un String formado por la intercalaci´on de las letras que forman ambos textos. Otro m´etodo que retorne el resultado de la comparaci´on entre dos substrings de los textos, recibiendo como par´ametros los ´ındices iniciales y finales para cada uno de ellos. Finalmente un m´etodo que permita reemplazar un cierto char por otro en ambos textos. Para esto puede ocupar s´olo los siguientes m´etodos de la clase String: charAt, length, equals, compareTo Criterios de soluci´on Lo primero que debemos hacer es declarar la clase Combinacion con dos atributos de tipo String. Luego debemos crear el constructor, el cual reciba dos Strings como par´ametros y los asigne a los atributos correspondientes. Para el m´etodo encargado de contar las apariciones de un char entregado como par´ametro, lo que tenemos que hacer es un ciclo (for por ejemplo) que recorra ambos Strings y vaya comparando cada uno de sus caracteres, utilizando el m´etodo charAt e ir contando en una variable cuantas veces el caracter es igual al recibido como par´ametro. Para el m´etodo que intercale ambos Strings lo que tenemos que hacer es nuevamente implementar un ciclo que vaya recorriendo cada String y obteniendo uno a uno sus caracteres con el m´etodo charAt. As´ı se concatena un caracter del primer String seguido de un caracter del segundo. En este m´etodo tenemos que revisar siempre que el String a´un no se acabe ya que puede ocurrir que uno sea m´as largo que el otro, en tal caso simplemente intercalamos hasta que se termine el menor y luego concatenamos el resto del mayor. Para el m´etodo que compara dos substrings de los textos debemos primero obtener los substrings seg´un los datos de inicio y fin recibidos como par´ametros. Para esto implementamos ciclos que recorran los strings desde el inicio hasta el fin recibidos como par´ametros y vayan formando los dos substrings, concatenando los caracteres que se obtienen utilizando el m´etodo charAt. Luego utilizando el m´etodo equals o compareTo, revisamos si son iguales, y retornamos true o false seg´un corresponda. Para el m´etodo que reemplace un char por otro lo que podemos hacer es implementar un ciclo que recorra ambos textos y que vaya obteniendo, con el m´etodo charAt, cada uno de los caracteres. Revi- samos el caracter comparando si es igual al que se quiere reemplazar. Si es as´ı, concatenamos el nuevo char, si no lo es, concatenamos el char original, formando as´ı el texto con los caracteres reemplazados. IIC1103 – Cap´ıtulo 5: Strings 15
  • 16. Posible soluci´on public class Combinacion { private String texto1 ; private String texto2 ; public Combinacion(String t1 , String t2) { texto1 = t1; texto2 = t2; } public int Apariciones(char c) { String t = texto1 + texto2 ; int apariciones = 0; for (int i = 0; i < t. length (); i++) { if (t.charAt (i) == c) { apariciones++; } } return apariciones; } public String Intercalacion() { String res = ""; for (int i = 0; i < texto1 .length () || i < texto2 .length (); i++) { if (i < texto1 .length ()) { res += texto1 .charAt (i); } if (i < texto2 .length ()) { res += texto2 .charAt (i); } } return res; } public boolean Comparar (int i1 , int f1 , int i2 , int f2) { // Obtenemos ambos substrings String t1 = ""; String t2 = ""; for (int i = i1; i <= f1; i++) { t1 += texto1 .charAt (i); } for (int i = i2; i <= f2; i++) { t2 += texto2 .charAt (i); } return t1.equals (t2); } public void Reemplazar(char charOriginal , char charReemplazo) { String aux = ""; for (int i = 0; i < texto1 .length (); i++) { if (texto1 .charAt (i) == charOriginal) { aux += charReemplazo; } else { aux += texto1 .charAt (i); } } texto1 = aux; aux = ""; for (int i = 0; i < texto2 .length (); i++) { if (texto2 .charAt (i) == charOriginal) { aux += charReemplazo; } else { aux += texto2 .charAt (i); } } texto2 = aux; } } IIC1103 – Cap´ıtulo 5: Strings 16
  • 17. Problema 8: C´odigo Simple Enunciado Haga un programa que dado un mensaje y un n´umero codifique el mensaje, moviendo las letras un n´umero de posiciones igual al n´umero ingresado, en la tabla ASCII. Por simplicidad puede transformar el mensaje a min´usculas. Adem´as escriba en el main una prueba del funcionamiento del programa. Criterios de soluci´on Seg´un el enunciado, primero debemos pedir al usuario el mensaje a codificar y un n´umero (lo llamaremos base del c´odigo). Dados estos n´umeros debemos obtener el valor de cada letra (s´olo las letras) en la tabla ASCII, y sumarle la base. Luego imprimiremos el mensaje, para mostrar el mensaje codificado. Para decodificar el mensaje el procedimiento es inverso, debemos restar la base, pero considerando que cambiaron los extremos en que los caracteres corresponden a letras (se suma la base a cada extremo). Adem´as debemos decodificar el mensaje con una base distinta, para mostrar que se requiere de ´esta para poder realizar la operaci´on. Posible soluci´on import iic1103Package.*; public class Principal { public static void main(String [] args) { String mensaje = Usuario . texto("Ingrese el mensaje que desea codificar."); int base = Usuario .entero (" Ingrese la base del codigo "); String codificado = codificar(mensaje , base); Usuario .mensaje (" Codificado:n" + codificado); Usuario .mensaje (" Decodificado Base 10:n" + decodificar(codificado , 10)); Usuario .mensaje (" Decodificado Base " + base + ":n" + decodificar(codificado , base )); } public static String codificar(String mensaje , int base) { String resultado = ""; mensaje = mensaje . toLowerCase(); for (int i = 0; i < mensaje .length (); i++) { if (mensaje .charAt (i) >= 97 && mensaje . charAt (i) <= 122) { resultado += (char) ( mensaje .charAt (i) + base ); } else { resultado += (char) mensaje .charAt (i); } } return resultado; } public static String decodificar(String mensaje , int base) { String resultado = ""; mensaje = mensaje . toLowerCase(); for (int i = 0; i < mensaje .length (); i++) { if (mensaje .charAt (i) >= 97 + base && mensaje .charAt (i) <= 122 + base) { resultado += (char) ( mensaje .charAt (i) - base ); } else { resultado += (char) mensaje .charAt (i); } } return resultado; } } IIC1103 – Cap´ıtulo 5: Strings 17
  • 18. Problema 9: Ahorcado Enunciado Realice un programa en Java para jugar “Al ahorcado”. Recuerde que este juego consiste en tratar de adivinar una palabra, letra por letra, en una cantidad preestablecida de intentos. Para este problema suponga que la palabra (oraci´on 1 ) a adivinar es “hola mundo”, aceptando a lo m´as 3 intentos fallidos por parte del usuario. Solicite a trav´es de una ventana al usuario que ingrese las letras, y muestre en consola la palabra con las letras que lleva descubiertas. Ejemplo: si el mensaje es “hola mundo”, y el usuario a ingreso “o”, “a”, “z”, debe mostrar en consola _o_a ____o . Por simplicidad puede suponer que tanto el mensaje secreto, como las letras ingresadas por el usuario, son en min´uscula. Criterios de soluci´on El enunciado nos da pocas restricciones, salvo el mensaje y la cantidad de intentos. Pero sabemos que debemos validar que el usuario ingrese s´olo una letra, comparar si corresponde a alguna(s) de la palabra secreta, y de ser as´ı cambiarla. Repetir esto mientras no haya ganado (descifrado la palabra completa) o perdido (alcanzado el m´aximo de errores permitidos). Posible soluci´on import iic1103Package.*; public class PrincipalAhorcado { /** * Programa para jugar el juego del Ahorcado */ public static void main(String [] args) { String palabraClave = "hola mundo"; // palabra clave establecida int intentos = 3; // cantidad de intentos establecidos // creamos un objetos de la clase Ahorcado Ahorcado a1 = new Ahorcado (palabraClave , intentos ); // mostramos el mensaje inicial Usuario .mensaje (" Bienvenido! " + "nIntente adivinar la palabra secreta . Tiene " + intentos + " intentos "); // ciclo del juego (mientras pueda seguir jugando ) while (a1.seguirJugando()) { // mostrar lo que lleva Usuario .mensaje ("Hasta ahora lleva: " + a1. getPalabraActual()); // guardaremos la letra que ingrese el usuario String palabra = ""; // verificamos que sea solo una letra while (palabra .length () != 1) { palabra = Usuario .texto ("Ingrese la letra que quiere descubrir: "); } // tomamos el primer caracter del string char c = palabra .charAt (0); // preguntar si esta en la palabra secreta a1. preguntarLetra(c); } // fuera del while (se acabo el juego) // vemos si gano if (a1.gano ()) { // mostramos el mensaje de felicitacion Usuario .mensaje (" Felicitaciones! Ha descubierto la palabra secreta "); } else { // perdio , mostramos el mensaje avisando Usuario .mensaje ("Ha perdido ." + "n La palabra era: " + a1. getPalabraClave()); } } } 1si ingresa una oraci´on, los espacios no se deben ocultar, es decir, colocando el “ ” IIC1103 – Cap´ıtulo 5: Strings 18
  • 19. public class Ahorcado { // [ ATRIBUTOS] String palabraClave; // palabra clave del juego String palabraActual; // palabra que lleva el usuario int intentosFallidos; // cantidad de intentos fallidos int intentosMaximo; // cantidad de intentos maximos por fallar // [METODOS ] // Constructor de la clase public Ahorcado (String palabraClave , int intentosMaximo) { this. palabraClave = palabraClave; this. intentosFallidos = 0; this. intentosMaximo = intentosMaximo; this. palabraActual = ocultarPalabra( palabraClave); } // getters public int getIntentosActual() { return intentosFallidos; } public String getPalabraActual() { return palabraActual; } public String getPalabraClave() { return palabraClave; } // Otros ... // metodo que determina si la letra esta en la palabra clave public void preguntarLetra(char c) { if (this.palabraClave. contains (c + "")) { descubrirLetra(c); } else { this. intentosFallidos++; } } // metodo que cambia cada "_" por la letra que corresponde public void descubrirLetra(char c) { String aux = ""; for (int i = 0; i < this. palabraClave.length (); i++) { if (this.palabraClave. charAt (i) == c) { aux += this. palabraClave.charAt (i); } else { aux += this. palabraActual.charAt (i); } } this. palabraActual = aux; } // esconde la palabra clave , cambiando cada caracter por "_" public String ocultarPalabra(String m) { String s = ""; for (int i = 0; i < m. length (); i++) { if (m.charAt (i) == ’ ’) { s += " "; } else { s += "_"; } } return s; } // determina si se puede seguir jugando (no ha ganado ni perdido ) public boolean seguirJugando() { if (this.intentosFallidos < this. intentosMaximo && !gano ()) { return true; } else { return false; } } // determina si gano public boolean gano() { return this.palabraClave. equals (this. palabraActual); } } IIC1103 – Cap´ıtulo 5: Strings 19
  • 20. Problema 10: Jerigonza Enunciado La jerigonza, jerigonzo o jerigoncio es una variante l´udica del habla2 . En jerigonza “escondido” se dice epescopondipidopo. Adem´as del entretenimiento, tambi´en puede usarse como un modo de codificar el mensaje de forma que otras personas cercanas a los hablantes no acostumbrados a esta forma de hablar no consigan entender lo que los hablantes dicen. Se le pide realizar un programa que codifique, y decodifique, mensajes escritos en este dialecto. Para ello, se sabe que despu´es de cada vocal se agrega el sonido “p” y se repite la vocal 3 . “Carlos” genera “Caparlopos”. Por simplicidad, puede asumir que el usuario ingresar´a texto sin tildes Ejemplo: (conversaci´on) Hopolapa, ¿copomopo epestapas? (Hola, ¿como estas?) Yopo epestopoypi bipiepen, ¿ypi tupu? (Yo estoy bien, ¿y tu?) Tapambiepen, grapacipiapas. (Tambien, gracias.) Epestapamopos hapablapandopo epen jeperipigoponzapa (Estamos hablando en jerigonza) Epesopo yapa lopo sapabipiapa (Eso ya lo sabia) Criterios de soluci´on Es realmente f´acil. Debemos revisar cada letra: si es una vocal se repite como dice el enunciado, y cualquier otro caracter se deja igual, salvo la “y” que se considerar´a como vocal, siempre y cuando lo que siga no sea una vocal (en este caso, hay que cuidar que no pasemos el largo del string). 2http://es.wikipedia.org/wiki/Jerigonza 3la letra “y” tambi´en ser´a considerada como vocal cuando corresponda, esto es, cuando no anteceda a alguna vocal IIC1103 – Cap´ıtulo 5: Strings 20
  • 21. Posible soluci´on import iic1103Package.*; public class Jerigonza { /** * Programa que escribe el texto ingresado por el usuario como Jerigonza. * (se asume que no ingresa ningun tipo de tilde) */ public static void main(String [] args) { String texto = Usuario .texto ("Ingrese el texto a Jerigonzar"); String cambiado = cambiar (texto ); Usuario .mensaje (cambiado ); } private static String cambiar (String texto) { String aux = ""; for (int i = 0; i < texto .length (); i++) { if (texto.charAt (i) == ’a’) { aux += "apa"; } else if (texto.charAt (i) == ’A’) { aux += "Apa"; } else if (texto.charAt (i) == ’e’) { aux += "epe"; } else if (texto.charAt (i) == ’E’) { aux += "Epe"; } else if (texto.charAt (i) == ’i’) { aux += "ipi"; } else if (texto.charAt (i) == ’I’) { aux += "Ipi"; } else if (texto.charAt (i) == ’o’) { aux += "opo"; } else if (texto.charAt (i) == ’O’) { aux += "Opo"; } else if (texto.charAt (i) == ’u’) { aux += "upu"; } else if (texto.charAt (i) == ’U’) { aux += "Upu"; } else if (texto.charAt (i) == ’y’ && ((i < texto. length () - 1) && texto. charAt (i + 1) != ’a’ && texto.charAt (i + 1) != ’A’ && texto.charAt (i + 1) != ’e’ && texto.charAt (i + 1) != ’E’ && texto.charAt (i + 1) != ’i’ && texto.charAt (i + 1) != ’I’ && texto.charAt (i + 1) != ’o’ && texto.charAt (i + 1) != ’O’ && texto.charAt (i + 1) != ’u’ && texto .charAt (i + 1) != ’U’)) { aux += "ypi"; } else if (texto.charAt (i) == ’Y’ && ((i < texto. length () - 1) && texto. charAt (i + 1) != ’a’ && texto.charAt (i + 1) != ’A’ && texto.charAt (i + 1) != ’e’ && texto.charAt (i + 1) != ’E’ && texto.charAt (i + 1) != ’i’ && texto.charAt (i + 1) != ’I’ && texto.charAt (i + 1) != ’o’ && texto.charAt (i + 1) != ’O’ && texto.charAt (i + 1) != ’u’ && texto .charAt (i + 1) != ’U’)) { aux += "Ypi"; } else { aux += texto.charAt (i); } } return aux; } } IIC1103 – Cap´ıtulo 5: Strings 21
  • 22. Problema 11: Cifrado ROT13 Enunciado Implemente una clase para encriptar/desencriptar mensajes utilizando el mecanismo de cifrado ROT13. La clase debe contener por lo menos dos m´etodos: public static String cifrar(String msg); Encripta un mensaje en ROT13. public static String descifrar(String msg); Desencripta un mensaje en ROT13. Descripci´on de ROT13 (http://es.wikipedia.org/wiki/Rot13/): “ROT13 (“rotar 13 posiciones”) es un sencillo cifrado C´esar utilizado para ocultar un texto sustituyendo cada letra por la letra que est´a trece posiciones por delante en el alfabeto. A se convierte en N, B se convierte en O y as´ı hasta la M, que se convierte en Z. Luego la secuencia se invierte: N se convierte en A, O se convierte en B y as´ı hasta la Z, que se convierte en M. Este algoritmo se utiliza en foros de Internet como medio para ocultar de miradas casuales el final de un chiste, la soluci´on a un acertijo, un spoiler de una pel´ıcula o una historia, o alg´un texto ofensivo. ROT13 se ha descrito como el “equivalente en Usenet de una revista que imprime bocabajo la respuesta a un pasatiempo”. El nombre “ROT13” se origin´o en Usenet a principios de los 80, y el m´etodo se ha convertido en un est´andar de facto. El ROT13 no proporciona seguridad criptogr´afica real y no se usa para tales fines; de hecho, a menudo se usa como ejemplo can´onico de cifrado d´ebil. Otra caracter´ıstica de este cifrado es que es sim´etrico; esto es, para deshacer el ROT13, se aplica el mismo algoritmo, de manera que para cifrar y descifrar se puede utilizar el mismo c´odigo.” Criterios de soluci´on Primero debemos tener en cuenta que este mecanismo s´olo toma en consideraci´on las 26 letras del abecedario, sin considerar la ˜n. Luego, debemos sumar 13 posiciones a cada car´acter; si se ”pasa”de la z, volvemos a la a. Como sabemos que lo char se pueden operar como si fueran enteros, basta con sumar 13 a cada char del String. Un punto muy importante es darse cuenta de que el mecanismo para descifrar es exactamente el mismo que para cifrar, por lo tanto no hace falta replicar el c´odigo sino que simplemente el m´etodo descifrar(..) har´a un llamado al m´etodo cifrar(..). IIC1103 – Cap´ıtulo 5: Strings 22
  • 23. Posible soluci´on public class Cifrado { // Declaro un metodo con nombre "cifrar "; retorna una variable de tipo // String y recibe como argumento otro String . public static String cifrar (String msg) { // Creo una variable de tipo String y la inicializo con un String vacio . String msgRot13 = ""; for (int i = 0; i < msg. length (); ++i) { // Creo una variable de tipo char y almaceno el caracter que se // encuentra en la posicion i del String msg. char x = msg.charAt (i); // A continuacion utilizare un "truco" para comparar caracteres // utilizando su valor en la tabla ASCII. // Noten que para escribir un caracter uso comillas simples en vez // de comillas dobles , ya que las comillas dobles sirve para // declarar variables de tipo String . // Si el caracter es mayor o igual que ’A’ (en la tabla ASCII) y // menor o igual que ’Z’ // (esto quiere decir: "si el caracter es una letra mayuscula") if (x >= ’A’ && x <= ’Z ’) { // Si me paso de Z, entonces le resto 13 al caracter . if (x + 13 > ’Z’) { x -= 13; } else { // Sino le sumo 13. x += 13; } // Si el caracter es una letra minuscula , entonces ... } else if (x >= ’a’ && x <= ’z’) { // Si me paso de Z, entonces le resto 13 al caracter . if (x + 13 > ’z’) { x -= 13; } else { // Sino le sumo 13. x += 13; } } // Agrego x al resultado. msgRot13 += x; } // Retorno el String cifrado . return msgRot13 ; } // En ROT13 el cifrado y descifrado se realiza con la misma funcion , por lo // tanto en el // metodo descifrar simplemten llamo al metodo cifrar y retorno su valor . public static String descifrar(String msg) { return cifrar (msg); } } IIC1103 – Cap´ıtulo 5: Strings 23
  • 24. Problema 12: Codificaci´on Enunciado El algoritmo de codificaci´on del capit´an Crunch codifica un mensaje de texto tomando cada una de sus letras y sum´andole 13. Por ejemplo, se convierte la letra ’a’ en ’ n ’ y la letra ’ b ’ en ’ o’. Las letras que se obtienen forman una anillo al final, por lo que al codificar la letra ’z’ ´esta se convierte en ’m’. El procedimiento general para codificar entonces, corresponde a sumar 13 a cada una de las letras, y para decodificar restar 13 a cada letra. El m´etodo del capit´an Crunch se puede generalizar, de manera que, en lugar de agregar 13 a las letras, se agregue un n´umero cualquiera. Usted deber´a implementar la clase Codificador la cual permite codificar y decodificar mensajes usando el algoritmo antes descrito. Puede suponer que el mensaje s´olo contiene letras min´usculas del alfabeto ingl´es (i.e. sin ’ch’, ’ll’, ni ’˜n’). En detalle, su c´odigo deber´a cumplir con lo siguiente: Su clase debe proveer de un m´etodo constructor que reciba como par´ametro la cantidad que se debe sumar o restar a cada una de letras para codificar o decodificar un mensaje. El constructor debe verificar que el valor recibido sea un entero mayor o igual que 0, y menor o igual que 26. El constructor adem´as debe ser capaz de establecer si fue creado en forma exitosa para que cuando el objeto sea utilizado para codificar o decodificar, se pueda determinar si la operaci´on se puede ejecutar o no. Escriba un m´etodo que permita codificar y decodificar un mensaje. El m´etodo recibe como par´ametro el mensaje y un boolean que indica si se desea codificar (true) o decodificar (false). El m´etodo retorna un String con el mensaje codificado o decodificado seg´un sea el caso. En caso que el objeto codificador no haya sido inicializado en forma exitosa retorna el mensaje ”#ERROR#”. Para esto puede ocupar s´olo los siguientes m´etodos de la clase String: charAt, length, equals, compareTo Criterios de soluci´on Lo primero que debemos hacer, como nos indica el enunciado, es implementar el constructor de la clase. ´Este debe recibir el n´umero que se sumar´a y restar´a para encriptar y desencriptar y guardarlo como atributo. Adem´as, como debemos mostrar si el objeto pudo ser creado con ´exito, y el constructor no puede retornar nada, agregamos otro atributo a la clase que indique si el objeto se cre´o bien o no. Para el m´etodo encriptar lo que primero tenemos que hacer es revisar si el objeto se cre´o con ´exito. Si no fue as´ı retornamos el mensaje de error. Luego tenemos que determinar si el usuario desea encriptar o desencriptar, para saber si sumar o restar a cada caracter. A continuaci´on, debemos sumar (o restar) tantas posiciones como valor determinado por el usuario en el constructor, a cada car´acter; si se ”pasa”de la z, volvemos a la a. Como sabemos que los char se pueden operar como si fueran enteros, basta con sumar (o restar) la cantidad adecuada a cada char del String. IIC1103 – Cap´ıtulo 5: Strings 24
  • 25. Posible soluci´on public class Codificador { private int millave ; private boolean habilitado; public Codificador(int llave ) { if (( llave >= 0) && (llave <= 26)) { millave = llave; habilitado = true; } else { habilitado = false; } } public String encriptar(String mensaje , boolean encriptar) { String encriptado = ""; int cero = ’a’ - 1; int llaveActual = millave ; if (! encriptar) llaveActual *= -1; for (int i = 0; i < mensaje .length (); i++) { char letra = mensaje . charAt (i); int valor = letra; if (letra != ’ ’) { valor = letra + llaveActual - cero; if (encriptar) { if (valor > 26) valor %= 26; } else { if (valor < 0) valor = 26 + valor ; } valor += cero; } encriptado += (char) ( valor ); } if ( habilitado) return encriptado; return "#ERROR#"; } } IIC1103 – Cap´ıtulo 5: Strings 25
  • 26. Problema 13: Encriptar Enunciado Se desea enviar mensajes encriptados. Para ello, Ud. deber´a crear un algoritmo que encripte un mensaje cualquiera, siguiendo esta estrategia: Ordene el mensaje ingresado, de manera que forme un cuadrado perfecto (el n´umero de filas es igual al n´umero de columnas). No debe considerar los espacios en blanco. En caso de que el n´umero de letras no den un cuadrado perfecto, a˜nada el caracter de relleno ”@”. Finalmente, lea el mensaje de arriba abajo y de izquierda a derecha. A continuaci´on se presenta un ejemplo: // Mensaje original "Mensaje a ser encriptado" // Este seria nuestro cuadrado , se eliminan los espacios y se agregan @ Mensa jease rencr iptad o@@@@ // Mensaje resultante " Mjrioeeep@nant@ssca@aerd@" Aqu´ı se encuentra la clase principal Encriptador que hace uso de la clase Cypher. Ud. deber´a implementar todos los m´etodos de la clase Cypher que son invocados por el Encriptador: import iic1103Package.*; public class Encriptador { public static void main(String [] args) { Cypher c = new Cypher (); String msg = Usuario .texto ("Ingrese el mensaje a encriptar"); // Quitar espacios del mensaje ingresado msg = c.QuitarEspacios(msg); // Determinar el tamanio del Cuadrado (nro. filas = nro. columnas ) int nro_filas = c. CuadradoPerfecto(msg); // Algoritmo de encriptacion String msg2 = c. Encriptar(msg , nro_filas); Usuario .mensaje (msg2); } } Criterios de soluci´on M´etodo QuitarEspacios: En este m´etodo tenemos que recorrer el String e ir obteniendo cada caracter con el m´etodo charAt y revisar si es igual al caracter que representa el espacio. Si no es igual lo concatenamos al String final. As´ı el String que retornamos no contiene ning´un espacio. M´etodo CuadradoPerfecto: En este m´etodo tenemos que determinar el n´umero de filas (igual al n´umero de columnas). Para esto utilizamos el m´etodo Math.sqrt con el largo del String, considerando que si la raiz no es exacta tenemos que sumar uno al resultado para poder considerar todas las letras del mensaje. M´etodo Encriptar: Lo primero que tenemos que hacer es revisar si el mensaje ocupa todas las posi- ciones del cuadrado. De no ser as´ı debemos rellenar los caracteres que faltan con ’@’. Despu´es para encriptar lo importante es recorrer bien el String. As´ı, partimos desde el comienzo y con un ciclo vamos recorriendo todo el String. Dentro de este ciclo implementamos otro, el cual vaya ob- teniendo los caracteres para concatenar en la respuesta final. Para obtener los caracteres tenemos que avanzar tantas posiciones como el n´umero de columnas tenga el cuadrado, as´ı estaremos recorriendo el cuadrado leyendo por columna. IIC1103 – Cap´ıtulo 5: Strings 26
  • 27. Posible soluci´on public class Cypher { public String Encriptar(String s, int total) { String respuesta = ""; // aniadir caracteres extra while (s.length () < (total * total )) s = s + "@"; // llenar el cuadrado for (int i = 0; i < total ; i++) { for (int j = i; j < s. length (); j = j + total ) respuesta = respuesta + s.charAt (j); } return respuesta; } public int CuadradoPerfecto(String s) { int total = (int) Math.sqrt(s.length ()); if ( total * total != s. length ()) total ++; return total; } public String QuitarEspacios(String s) { String otro = ""; for (int i = 0; i < s. length (); i++) { if (s.charAt (i) != ’ ’) otro += s.charAt (i); } return otro; } } IIC1103 – Cap´ıtulo 5: Strings 27
  • 28. Problema 14: Nombre de Usuario Enunciado Cada alumno de la Universidad tiene un nombre de usuario, que es el nombre al cual se le env´ıa e-mail en el dominio de la Universidad. Este nombre de usuario se determina a partir del nombre real del alumno y est´a compuesto por 8 caracteres que pueden ser letras o n´umeros. Escriba la clase NombredeUsuario, que tiene como atributos al menos el nombre real del alumno, el nombre de usuario inicial, y el nombre de usuario final. Adem´as, esta clase debe tener al menos los siguientes tres m´etodos: Un constructor, que recibe como par´ametros cuatro strings, correspondientes al primer nombre, segundo nombre, primer apellido y segundo apellido del alumno. Si el alumno tiene s´olo un nombre, el par´ametro correspondiente al segundo nombre es un String vac´ıo. En el atributo, el nombre real del alumno debe quedar escrito en la forma familiar <primer nombre> <segundo nombre> <primer apellido> <segundo apellido>, o bien <primer nombre> <primer apellido> <segundo apellido> (notar que hay espacios en blanco). Un m´etodo nombreUsuarioInicial, que determina el nombre de usuario inicial del alumno, a partir de su nombre real, y lo guarda en el atributo correspondiente. El nombre de usuario inicial est´a formado por la inicial del primer nombre, seguido por la inicial del segundo nombre, y seguido por las seis primeras letras del primer apellido (para totalizar los 8 caracteres) Si el alumno no tiene segundo nombre, entonces la inicial del segundo nombre es reemplazada por la segunda letra del primer nombre. Si el primer apellido tiene menos de seis letras, entonces las letras faltantes son reemplazadas por las primeras letras del segundo apellido. Un m´etodo nombreUsuarioFinal , que recibe como par´ametro un string con todos los nombres de usuario v´alidos en la Universidad (cada uno separado por un punto), y que determina el nombre de usuario final del alumno y lo guarda en el atributo correspondiente. Para determinar el nombre de usuario final hay que revisar el string de nombres de usuario v´alidos. Si el nombre de usuario inicial no aparece en el string, entonces el nombre de usuario final es igual al inicial. En cambio, si el nombre de usuario inicial aparece en el string, entonces el nombre de usuario final se determina de la siguiente manera: se elige aleatoriamente un n´umero entre 1 y 7, y se cambia la letra que est´a en esa posici´on en el nombre de usuario inicial por uno de los d´ıgitos 1 al 9, tambi´en elegido aleatoriamente. Suponga que siempre la cantidad de letras del apellido paterno m´as la cantidad de letras del apellido materno es al menos 6. Criterios de soluci´on Atributos: Lo primero que tenemos que hacer es declarar los atributos de la clase como nos indican el enunciado. Para esto utilizamos 3 Strings para guardar el nombre de usuario inicial, el nombre real y el nombre de usuario final. Adem´as podemos guardar los nombres y apellidos del usuario en otros Strings. Constructor: Recibimos los par´ametros que nos indica el enunciado y revisamos si el segundo nombre viene nulo. Seg´un esto formamos el nombre real. M´etodo nombreUsuarioInicial : Lo primero que tenemos que hacer es revisar si el usuario tiene segundo nombre. Si es as´ı tomamos el primer caracter (con el m´etodo charAt()) del primer nombre y el primer caracter del segundo nombre. Si no, tomamos los dos primeros caracteres del primer nombre. Concatenamos los caracteres obtenidos en el atributo que representa el nombre de usuario inicial. Luego, revisamos, con el m´etodo length(), si el apellido del usuario tienen m´as de 6 letras. Si es as´ı, con el m´etodo substring obtenemos las 6 primeras letras y las concatenamos al nombre de usuario IIC1103 – Cap´ıtulo 5: Strings 28
  • 29. inicial. Si no, calculamos cuantas letras nos faltan y adem´as del primer apellido concatenamos las letras que faltan del segundo apellido. M´etodo nombreUsuarioFinal: Recibimos el String con los nombres de usuario ya existente y utilizando el m´etodo contains revisamos si el nombre de usuario formado est´a contenido en los nombres de usuarios recibidos. Si es as´ı, generamos aleatoriamente dos n´umeros: uno que determine la posici´on y otro que sea el n´umero a intercalar en esa posici´on. Luego con el m´etodo substring separamos el nombre de usuario inicial en dos y luego concatenamos la primera mitad, m´as el d´ıgito generado aleatoriamente m´as la segunda mitad y tenemos el nombre de usuario final. Posible soluci´on import iic1103Package.*; public class NombredeUsuario { private String nombreReal; private String nomUsuIni; private String nombreUsuario; private String nombre1 , nombre2 , apellido1 , apellido2; public NombredeUsuario(String nom1 , String nom2 , String ap1 , String ap2) { nombre1 = nom1; nombre2 = nom2; apellido1 = ap1; apellido2 = ap2; if (nom2.length () == 0) { nombreReal = nombre1 + " " + apellido1 + " " + apellido2; } else { nombreReal = nombre1 + " " + nombre2 + " " + apellido1 + " " + apellido2; } } public void nombreUsuarioInicial() { if ( nombre2 .length () == 0) { nomUsuIni = "" + nombre1 .charAt (0) + nombre1 .charAt (1); } else { nomUsuIni = "" + nombre1 .charAt (0) + nombre2 .charAt (0); } if ( apellido1.length () >= 6) { nomUsuIni = nomUsuIni + apellido1. substring(0, 6); } else { int k = 6 - apellido1. length (); nomUsuIni = nomUsuIni + apellido1 + apellido2.substring(0, k); } } public void nombreUsuarioFinal(String usuarios ) { if (! usuarios .contains ( nomUsuIni)){ nombreUsuario = nomUsuIni; } else { int p = Aleatorio.entero (1, 7); int q = Aleatorio.entero (1, 9); nombreUsuario = nomUsuIni.substring(0, p) + q + nomUsuIni. substring(p + 1, 8); } } } IIC1103 – Cap´ıtulo 5: Strings 29
  • 30. Problema 15: Mensaje Oculto Enunciado El servicio secreto le ha encomendado la tarea de implementar un programa que pueda descifrar mensajes ocultos que se esperan recibir de un agente encubierto en la mafia de las revistas de far´andula. Se espera que este agente utilice el primer y ´ultimo caracter de cada l´ınea de los textos para esconder los mensajes, de manera que para leer el mensaje se deben leer los primeros caracteres de cada l´ınea desde arriba hacia abajo y luego seguir con los ´ultimos caracteres de cada l´ınea pero desde abajo hacia arriba (salvo la ´ultima l´ınea, en la cu´al s´olo se considera en el mensaje su primer car´acter). Adem´as, si el car´acter es una letra may´uscula, implicar´a que comienza una nueva palabra en el mensaje oculto, mientras que si es un punto ‘.’ o coma ‘,’ ser´a equivalente a un espacio (que separar´a dos palabras contiguas). Por ejemplo, si tenemos el siguiente texto: Mientras con ansias a su perro esperaba, muchas preocupaciones Gustavo ten´ıa. Esperar unos minutos m´as su espiritu socavaba escuchando el tic tac tembloroso de su reloj. Sin embargo, a pesar de la larga espera, finalmente Einstein, su perro, volvi´o a su apreciado habitat sembrando la alegr´ıa en su querido amigo. El mensaje resultante ser´a “Me Gusta Este curso” (no se preocupe de may´usculas y min´usculas en el mensaje resultante). En concreto, se le solicita que escriba una clase Decifrador con un constructor que reciba el texto a descifrar y un m´etodo descubrirMensaje que entregue como resultado el mensaje descifrado a partir del texto (sin perjuicio de que adem´as agregue todos los atributos y m´etodos que estime necesarios). De esta manera, su clase deber´a poder ser usada de la siguiente forma: String mensaje = "Mientras con ansias a su perro n esperaba, muchas preocupacionesn Gustavo ten´ıa. Esperarn unos minutos m´as su esp´ıritun socavaba escuchando el tic tacn tembloroso de su reloj. Sin embargo,n a pesar de la larga espera, finalmente nEinstein, su perro, volvi´o a su habitatn sembrando alegr´ıa en su querido amigo."; Decifrador decifrador = new Decifrador(mensaje); Usuario.mensaje(decifrador.descubrirMensaje()); NOTA: Puede suponer que no habr´a caracteres con tilde (´a, ´e, ´ı,. . . ) ni ˜n al principio y final de cada l´ınea. Criterios de soluci´on Constructor: Simplemente recibimos como par´ametro un String que represente el mensaje y lo asigna- mos al atributo de la clase. M´etodo descubrirMensaje: En este m´etodo recorremos el String buscando el caracter de fin de l´ınea (obtenemos cada caracter con el m´etodo charAt()). Cuando encontramos el salto de l´ınea obtenemos el caracter que est´a a la izquierda (que ser´ıa el ´ultimo caracter de la l´ınea) y el que est´a a la derecha (que ser´ıa el primer caracter de la siguiente l´ınea). Revisamos si se trata de un caracter especial (como IIC1103 – Cap´ıtulo 5: Strings 30
  • 31. punto ‘.’ o coma ‘,’ o una letra may´uscula) para agregar espacios cuando corresponda y formamos dos strings: uno que represente las letras iniciales de cada l´ınea y otro las finales, tomando en cuenta que al que represente las letras finales hay que ir agregando los nuevos caracteres al inicio y no al final. As´ı despu´es concatenamos estos dos Strings y tenemos el mensaje descifrado. Posible soluci´on public class Descifrador { private String texto; public Descifrador(String texto) { this. texto = texto; } public String descubrirMensaje() { String resultadoIzquierdo = "" + texto.charAt (0); String resultadoDerecho = ""; char caracterIzquierdo; char caracterDerecho; for (int i = 1; i < texto .length () - 1; i++) { char caracterActual = texto.charAt (i); if (caracterActual == ’n’) { caracterIzquierdo = texto.charAt (i - 1); caracterDerecho = texto .charAt (i + 1); resultadoIzquierdo += interpretarCaracter(caracterDerecho); resultadoDerecho = interpretarCaracter( caracterIzquierdo) + resultadoDerecho; } } return resultadoIzquierdo + resultadoDerecho; } private String interpretarCaracter(char caracter ) { if ( caracter >= ’A’ && caracter <= ’Z’) { return " " + caracter ; } else if (caracter == ’.’ || caracter == ’,’) { return " "; } return "" + caracter ; } } IIC1103 – Cap´ıtulo 5: Strings 31
  • 32. Problema 16: Tap Code Enunciado El Tap Code es una forma de encriptar mensajes usada por prisioneros en Vietnam. Es un m´etodo muy simple que consiste en traducir cada letra de un mensaje en una serie de sonidos hechos con metal, madera, etc. (”taps”) y pausas. Tambi´en puede ser representado gr´aficamente. En este caso cada letra se traduce en dos series de puntos separados por un espacio, que representan dos n´umeros indicando la fila y columna que corresponde a la letra en una matriz de claves de 5x5. Por ejemplo, dada la matriz de la figura, la letra ”D” est´a en la fila 1, columna 4, por lo que se representa por los puntos ”. ....”(1, 4). La palabra ”MENSAJE” se traducir´ıa de la siguiente manera. Las letras de una palabra tambi´en van separadas entre s´ı por 1 espacio, al final de la serie de puntos no debe ir un espacio. Otras consideraciones: la letra K se considera que es una C, la letra ˜N se considera como si fuera N, se ignora todo otro s´ımbolo fuera de la matriz de claves. Se pide que implemente el m´etodo aTap de la clase Cipher que recibe dos Strings, uno contiene el mensaje original, y el otro un String con los caracteres de la matriz, ambos Strings en may´usculas. El m´etodo aTap devuelve un String conteniendo la serie de puntos equivalentes en el Tap Code. Note que si recibe como mensaje un String vac´ıo o nulo, debe retornar el mismo mensaje original sin ning´un cambio. import iic1103Package.*; public class Principal { public static void main(String [] args) { String matriz = " ABCDEFGHIJLMNOPQRSTUVWXYZ"; Cypher c = new Cypher (); String mensaje = Usuario . texto("Mensaje ?"); // Convierte el mensaje a mayusculas mensaje = mensaje . toUpperCase(); Usuario .mensaje (c.aTap(mensaje , matriz )); } } public class Cypher { public String aTap(String original , String matriz ) { // Implementar el metodo que convierte a original en una // lista de puntos siguiendo las reglas del TapCode } } Criterios de soluci´on Lo primero que tenemos que hacer en el m´etodo aTap es revisar que el String original recibido como par´ametro no sea vac´ıo. Si es as´ı, simplemente retornamos el mismo String. IIC1103 – Cap´ıtulo 5: Strings 32
  • 33. Si el String no est´a vac´ıo debemos recorrerlo con un ciclo para obtener cada letra que lo compone, utilizando para esto el m´etodo charAt. Al obtener la letra debemos revisar si se trata de una C o una ˜N y cambiarlas a C y N respectivamente. Luego tenemos que encontrar la posici´on de la letra en la matriz recibida como par´ametro. Si vemos la matriz como un String extendido podemos ver que la fila de la letra estar´a dada por la posici´on de la letra en el String divido en 5 (ya que son 5 filas y 5 columnas). Y la columna de la letra estar´a dada por el resto de la divisi´on de la posici´on de la letra en el String por 5. Despu´es de eso s´olo tenemos que imprimir tantos puntos como la fila y la columna encontrada, separando cada uno con un espacio. Posible soluci´on public String aTap(String original , String matriz ) { if (( original == null) || original .equals ("")) { return original ; } String puntos = ""; for (int i = 0; i < original .length (); i++) { String letra = "" + original .charAt (i); if (letra.equals ("K")) { letra = "C"; } else if (letra.equals ("N")) { letra = "N"; } int n = -1, m = -1; if (matriz .indexOf (letra ) >= 0) { n = matriz .indexOf (letra ) / 5; m = matriz .indexOf (letra ) - n * 5; } if (n >= 0 && n >= 0) { for (int j = 0; j <= n; j++) { puntos = puntos + "."; } puntos = puntos + " "; for (int j = 0; j <= m; j++) { puntos = puntos + "."; } } puntos = puntos + " "; } // NO DEBE INCLUIR UN ESPACIO AL FINAL if ( puntos .length () > 0) { puntos = puntos . substring(0, puntos .length () - 1); } return puntos ; } IIC1103 – Cap´ıtulo 5: Strings 33
  • 34. Problema 17: Integrantes Familia Enunciado Usted deber´a realizar un programa que permita manejar a los integrantes de distintas familias, as´ı como a los pasatiempos de cada uno de esos integrantes. Para ello contar´a con un m´etodo main que ya viene implementado. 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. No puede utilizar el m´etodo contains de la clase String. Incremento 1 En este primer incremento deber´a definir lo b´asico de las clases Familia y Persona, de modo de poder crearlas. Una Persona est´a caracterizada por su nombre, su edad y su g´enero, el cual se representa con un 0 si es hombre o un 1 en caso que sea mujer. Adem´as cada persona tiene sus pasatiempos, los cuales se representan con un string en el cual se van concatenando los pasatiempos que se van agregando. Su clase Persona debe cumplir con los usos dados en el main dado, el cual usted no puede modificar. Por su parte Familia est´a caracterizado por los apellidos de la familia y por hasta 5 personas que son los integrantes de la familia. Al igual que Persona, Familia debe poder ser utilizada con el main predefinido, por lo que debe coincidir los nombres de los m´etodos que ah´ı se encuentran as´ı como los par´ametros de cada uno. Incremento 2 Ahora que ya est´an creadas las familias, debe agregar los m´etodos necesarios a sus clases para que sea posible mostrar en consola cada familia. Una familia se muestra indicando sus apellidos y el nombre, edad y g´enero de cada uno de sus integrantes. Este es un ejemplo de como se muestra una familia en consola: *************************************************** Familia : Palma Sepulveda Juan (25 - Hombre ) Maria (43 - Mujer) Pedro (12 - Hombre ) Pablo (48 - Hombre ) *************************************************** Adem´as cada familia debe ser capaz de retorna el promedio de edad de la familia, para que as´ı el main pueda mostrarlos. Incremento 3 Por ´ultimo debe ser posible buscar el n´umero de integrantes que tiene un cierto pasatiempo en cada familia. Pudiendo tambi´en realizar esta b´usqueda en un g´enero en particular. Nuevamente debe cumplir con lo defi- nido en el main. import iic1103Package.*; public class Principal { public static void main(String [] args) { /* *********************************************************************** * Iteracion 1 */ // Creamos todas las familias con sus respectivas personas y pasatiempos Familia f1 = new Familia ("Palma Sepulveda"); Persona p11 = new Persona (" Juan", 25, 0); p11. agregarPasatiempo("Futbol "); p11. agregarPasatiempo("Piano "); Persona p12 = new Persona (" Maria", 43, 1); p12. agregarPasatiempo("Leer"); Persona p13 = new Persona (" Pedro", 12, 0); p13. agregarPasatiempo("TV"); p13. agregarPasatiempo("Futbol "); IIC1103 – Cap´ıtulo 5: Strings 34
  • 35. Persona p14 = new Persona (" Pablo", 48, 0); p14. agregarPasatiempo("Leer"); p14. agregarPasatiempo("Futbol "); p14. agregarPasatiempo("Comer "); f1. agregarIntegrante(p11); f1. agregarIntegrante(p12); f1. agregarIntegrante(p13); f1. agregarIntegrante(p14); Familia f2 = new Familia ("Langdon Alarcon "); Persona p21 = new Persona (" Carolina ", 13, 1); p21. agregarPasatiempo("Bailar "); p21. agregarPasatiempo("Leer"); Persona p22 = new Persona (" Isabel ", 17, 1); p22. agregarPasatiempo("Cantar "); p22. agregarPasatiempo("Leer"); p22. agregarPasatiempo("Futbol "); Persona p23 = new Persona (" Jose", 30, 0); p23. agregarPasatiempo("Futbol "); p23. agregarPasatiempo("Comer "); f2. agregarIntegrante(p21); f2. agregarIntegrante(p22); f2. agregarIntegrante(p23); Familia f3 = new Familia ("Eterovic Zavala "); Persona p31 = new Persona (" Yadran ", 45, 0); p31. agregarPasatiempo("Tenis "); p31. agregarPasatiempo("Leer"); Persona p32 = new Persona (" Tere", 19, 1); p32. agregarPasatiempo("Comer "); p32. agregarPasatiempo("Leer"); p32. agregarPasatiempo("Bailar "); Persona p33 = new Persona (" Sole", 30, 1); p33. agregarPasatiempo("Leer"); Persona p34 = new Persona (" Sebastian", 52, 0); p33. agregarPasatiempo("Tenis "); p33. agregarPasatiempo("Cocinar "); p33. agregarPasatiempo("Comer "); Persona p35 = new Persona (" Francisco", 35, 0); p33. agregarPasatiempo("Futbol "); p33. agregarPasatiempo("Leer"); Persona p36 = new Persona (" Matias ", 25, 0); p33. agregarPasatiempo("Futbol "); p33. agregarPasatiempo("Cocinar "); f3. agregarIntegrante(p31); f3. agregarIntegrante(p32); f3. agregarIntegrante(p33); f3. agregarIntegrante(p34); f3. agregarIntegrante(p35); // El metodo agregar persona debe retornar false si no es posible // hacerlo porque ya esta llena la familia . if (! f3.agregarIntegrante(p36)) { Usuario .mensajeConsola("No se pudo agregar " + p36.getNombre() + " a la familia " + f3.getApellidos()); } Familia f4 = new Familia ("Peralta Jara"); Persona p41 = new Persona (" Fernando ", 26, 0); p41. agregarPasatiempo("Tenis "); p41. agregarPasatiempo("Leer"); p41. agregarPasatiempo("Cantar "); Persona p42 = new Persona (" Cata", 24, 1); p42. agregarPasatiempo("Bailar "); p42. agregarPasatiempo("Yoga"); p42. agregarPasatiempo("Cocinar "); p42. agregarPasatiempo("Viajar "); f4. agregarIntegrante(p41); f4. agregarIntegrante(p42); /* *********************************************************************** * Iteracion 2 */ // Mostramos cada familia f1. mostrarFamilia(); f2. mostrarFamilia(); f3. mostrarFamilia(); f4. mostrarFamilia(); IIC1103 – Cap´ıtulo 5: Strings 35
  • 36. // Mostramos el promedio de edad de cada familia Usuario .mensajeConsola("Edad Familia : " + f1. getApellidos() + " - " + f1.promedioEdad()); Usuario .mensajeConsola("Edad Familia : " + f2. getApellidos() + " - " + f2.promedioEdad()); Usuario .mensajeConsola("Edad Familia : " + f3. getApellidos() + " - " + f3.promedioEdad()); Usuario .mensajeConsola("Edad Familia : " + f4. getApellidos() + " - " + f4.promedioEdad()); /* *********************************************************************** * Iteracion 3 */ // Buscamos la cantidad de personas con pasatiempo Futbol en cada // familia Usuario .mensajeConsola("Personas que les gusta el futbol Familia : " + f1.getApellidos() + " - " + f1. integrantesConPasatiempo("Futbol ")); Usuario .mensajeConsola("Personas que les gusta el futbol Familia : " + f2.getApellidos() + " - " + f2. integrantesConPasatiempo("Futbol ")); Usuario .mensajeConsola("Personas que les gusta el futbol Familia : " + f3.getApellidos() + " - " + f3. integrantesConPasatiempo("Futbol ")); Usuario .mensajeConsola("Personas que les gusta el futbol Familia : " + f4.getApellidos() + " - " + f4. integrantesConPasatiempo("Futbol ")); // Ahora mostramos la cantidad de mujeres que les gusta leer por cada // familia Usuario .mensajeConsola("Mujeres que les gusta leer Familia : " + f1.getApellidos() + " - " + f1. integrantesConPasatiempoPorGenero("Leer", 1)); Usuario .mensajeConsola("Mujeres que les gusta leer Familia : " + f2.getApellidos() + " - " + f2. integrantesConPasatiempoPorGenero("Leer", 1)); Usuario .mensajeConsola("Mujeres que les gusta leer Familia : " + f3.getApellidos() + " - " + f3. integrantesConPasatiempoPorGenero("Leer", 1)); Usuario .mensajeConsola("Mujeres que les gusta leer Familia : " + f4.getApellidos() + " - " + f4. integrantesConPasatiempoPorGenero("Leer", 1)); } } Criterios de soluci´on Clase Persona • Atributos: Declaramos los atributos necesarios seg´un nos indican en el enunciado: dos String, uno para el nombre y otro para los pasatiempos y dos enteros, uno para representar la edad y otro para representar el g´enero. • Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametros el nombre, la edad y el genero y los asigna a los atributos correspondientes. • M´etodo agragarPasatiempo: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro un String con el hobbie a agregar y tenemos que concatenarlo al String que almacena los pasatiempos. • Getters: Seg´un el uso dado en la clase Principal necesitamos 3 m´etodos get para obtener el nombre, la edad y el g´enero. • M´etodo tienePasatiempo: Este m´etodo sirve para revisar si la persona tiene un determinado pasatiempo (para cumplir con lo pedido en el incremento 3), puede hacerse tambi´en s´olo en la clase Familia. Lo que hacemos es buscar el pasatiempo generando todos los substrings desde la lista de pasatiempos que tengan el mismo largo que el pasatiempo recibido y comparar hasta encontrar alguna coincidencia. • M´etodo mostrar: Revisamos el g´enero de la persona y seg´un eso mostramos en Consola su edad seguida de ’Hombre’ o ’Mujer’ seg´un corresponda. IIC1103 – Cap´ıtulo 5: Strings 36
  • 37. Clase Familia: • Atributos: Declaramos los atributos necesarios seg´un lo que se nos indica en el enunciado: un String para guardar los apellidos y cuatro objetos de la clase Persona que representen a los integrantes. • Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro un String con los apellidos y lo asigna al atributo correspondiente. • M´etodo agregarIntegrante: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro un objeto de la clase Persona. Tenemos que revisar a qu´e objeto, de los 4 que tenemos como atributos, debemos asignarlo, revisando cu´al de ellos es todav´ıa null. Retornamos true o false seg´un se pudo o no asignar el integrante. • M´etodo getApellidos: Retorna los apellidos de la familia. • M´etodo promedioEdad: Recorremos todas las personas y obtenemos su edad (cuidando que el integrante no sea null) calculando con esto el promedio. • M´etodo mostrarFamilia: Mostramos en la consola los apellidos de la familia y por cada persona mostramos su edad y si es hombre o mujer. • M´etodo integrantesConPasatiempo: Para no implementar un m´etodo dos veces simplemente llamamos al m´etodo integrantesConPasatiempoPorGenero definiendo un valor inv´alido para el g´enero. • M´etodo integrantesConPasatiempoPorGenero: Recorremos todas las personas y en cada una revisamos que no sea nula y que tenga el pasatiempo solicitado (llamando al m´etodo que imple- mentamos en la clase Persona). Adem´as, en caso que el g´enero sea v´alido, tambi´en revisamos que el genero de la persona corresponda. Si se cumplen ambas condiciones aumentamos el contador de personas, el cual retornamos al finalizar el m´etodo. Posible soluci´on import iic1103Package.*; public class Familia { // Definimos los atributos necesarios private String apellidos; // Definimos las personas que pueden integrar la familia private Persona integrante1; private Persona integrante2; private Persona integrante3; private Persona integrante4; private Persona integrante5; public Familia (String apellidos) { this. apellidos = apellidos; } public Persona obtenerPersona(int idx) { // Obtenemos la persona segun el indice de ella if (idx == 0) return integrante1; else if (idx == 1) return integrante2; else if (idx == 2) return integrante3; else if (idx == 3) return integrante4; else return integrante5; } public boolean agregarIntegrante(Persona p) { // Para agregar un nuevo integrante buscamos aquel que aun sea nulo if ( integrante1 == null) { integrante1 = p; } else if (integrante2 == null) { integrante2 = p; IIC1103 – Cap´ıtulo 5: Strings 37
  • 38. } else if (integrante3 == null) { integrante3 = p; } else if (integrante4 == null) { integrante4 = p; } else if (integrante5 == null) { integrante5 = p; } else { // Si no hay ninguno vacio entonces retornamos false return false; } return true; } public double promedioEdad() { // Declaramos una variable donde acumularemos double promedio = 0; int count = 0; // Recorremos todas las personas for (int i = 0; i < 5; i++) { Persona p = obtenerPersona(i); if (p != null) { // En caso de estar la persona acumulamos su edad promedio += p.getEdad (); count ++; } } return promedio / count; } public int integrantesConPasatiempo(String hobbie ) { // Llamamos al metodo que busca con genero definiendo un valor invalido // para el genero return integrantesConPasatiempoPorGenero(hobbie , -1); } public int integrantesConPasatiempoPorGenero(String hobbie , int genero ) { int count = 0; // Recorremos todas las personas for (int i = 0; i < 5; i++) { Persona p = obtenerPersona(i); // Revisamos que no sea nula y que tenga el pasatiempo solicitado. // Ademas en caso de que el // genero sea valido tambien restringimos por el if (p != null && p. tienePasatiempo(hobbie ) && (genero == -1 || p.getGenero() == genero )) count ++; } return count; } public void mostrarFamilia() { // Mostramos los apellidos y luego a cada una de las personas Usuario .mensajeConsola(" ***************************************************"); Usuario .mensajeConsola("Familia : " + apellidos); for (int i = 0; i < 5; i++) { Persona p = obtenerPersona(i); if (p != null) { p.mostrar (); } } Usuario .mensajeConsola(" ***************************************************"); } public String getApellidos() { return apellidos; } } import iic1103Package.*; public class Persona { // Definimos los atributos minimos necesarios private String nombre ; private int edad; private int genero ; private String pasatiempos; IIC1103 – Cap´ıtulo 5: Strings 38
  • 39. public Persona (String nombre , int edad , int genero ) { // Inicializamos los valores para la persona , en un principio no tiene // pasatiempos this. nombre = nombre ; this.edad = edad; this. genero = genero ; this. pasatiempos = ""; } public void agregarPasatiempo(String hobbie ) { // Al agregar un pasatiempo lo agregamos al String que los representa pasatiempos += " - " + hobbie ; } public String getNombre() { return nombre ; } public int getEdad () { return edad; } public int getGenero() { return genero ; } public boolean tienePasatiempo(String hobbie ) { // Buscamos el pasatiempo generando todos los substrings desde la lista // de pasatiempos que tengan el mismo largo que el pasatiempo recibido for (int i = 0; i <= pasatiempos.length () - hobbie .length (); i++) { String aux = pasatiempos.substring(i, i + hobbie .length ()); if (aux. equalsIgnoreCase(hobbie )) { return true; } } return false; } public void mostrar () { if ( genero == 0) { Usuario .mensajeConsola( nombre + " (" + edad + " - Hombre )"); } else { Usuario .mensajeConsola( nombre + " (" + edad + " - Mujer)"); } } } IIC1103 – Cap´ıtulo 5: Strings 39
  • 40. Problema 18: Modelos de Autom´ovil Enunciado Usted deber´a realizar un programa que permita manejar los modelos pertenecientes a distintas marcas de autom´oviles, as´ı como las caracter´ısticas de estos modelos. Para ello deber´a trabajar con un m´etodo main que ya viene implementado. 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 primer incremento deber´a definir lo b´asico de las clases Marca y Modelo, para poder crearlas. Un Modelo est´a caracterizado por el nombre del modelo, el a˜no en que sali´o al mercado, y el tipo de veh´ıculo que es, el cual se representa con un 0 si corresponde a un modelo sed´an, un 1 si se trata de un station wagon, y un 2 en caso que sea una camioneta. Adem´as cada modelo tiene sus propias caracter´ısticas, las cuales se representan con un string en el cual se van concatenando las caracter´ısticas que se van agregando al modelo. Su clase Modelo debe cumplir con los usos dados en el main provisto, el cual usted no puede modificar. Por su parte, una Marca est´a caracterizada por los modelos que componen su l´ınea de producci´on, pudiendo ser hasta cuatro como m´aximo. Al igual que Modelo, la clase Marca debe poder ser utilizada con el main predefinido, por lo que en su implementaci´on deben coincidir los nombres y par´ametros de los m´etodos que ah´ı se encuentran. Incremento 2 Ahora que ya est´an creadas las marcas y sus modelos, debe agregar los m´etodos necesarios a sus clases para que sea posible mostrar en consola el cat´alogo de cada marca. Para una marca, este cat´alogo se muestra indicando su nombre y, para cada uno de sus modelos, la informaci´on correspondiente al nombre del modelo, su a˜no y su tipo. Por ejemplo, para una de las marcas el mensaje debe mostrarse como el siguiente: *************************************************** Marca: Hyundai Accent, 2008, Sedan Sonata, 2007, Sedan H-1, 2005, Station Wagon *************************************************** Adem´as, cada marca debe ser capaz de retornar la cantidad de modelos del a˜no 2008 que posee en su cat´alogo, para que as´ı el main pueda mostrar los mensajes correspondientes. Incremento 3 Por ´ultimo, debe complementar sus clases de modo que sea posible imprimir el cat´alogo de cada marca s´olo con los modelos correspondientes a un a˜no espec´ıfico, como tambi´en buscar el n´umero de modelos que presenten una cierta caracter´ıstica en cada marca, permitiendo adicionalmente realizar esta b´usqueda para un tipo de veh´ıculo en particular. Nuevamente debe cumplir con lo ya definido en el m´etodo main que se le entrega al comenzar su trabajo. IIC1103 – Cap´ıtulo 5: Strings 40
  • 41. import iic1103Package.*; public class Principal { public static void main(String [] args) { /** Incremento 1 */ // Creamos marcas y agregamos modelos con distintas caracteristicas Marca marca1 = new Marca("Hyundai "); Modelo modelo11 = new Modelo ("Accent ", 2008 , 0); modelo11 . agregarCaracteristica("Llantas "); modelo11 . agregarCaracteristica(" Alzavidrios Electricos"); modelo11 . agregarCaracteristica("Radio CD"); modelo11 . agregarCaracteristica("Mecanico "); modelo11 . agregarCaracteristica("Aire Acondicionado"); Modelo modelo21 = new Modelo ("Sonata ", 2007 , 0); modelo21 . agregarCaracteristica("Aire Acondicionado"); modelo21 . agregarCaracteristica(" Automatico"); modelo21 . agregarCaracteristica(" Neblineros"); modelo21 . agregarCaracteristica(" Alzavidrios Electricos"); modelo21 . agregarCaracteristica("Radio CD"); modelo21 . agregarCaracteristica("Alarma "); modelo21 . agregarCaracteristica("Tapiz de cuero"); modelo21 . agregarCaracteristica("Air Bag"); modelo21 . agregarCaracteristica(" Direccion Asistida "); Modelo modelo31 = new Modelo ("H-1", 2005 , 1); modelo31 . agregarCaracteristica("Alarma "); modelo31 . agregarCaracteristica("Mecanico "); modelo31 . agregarCaracteristica("Radio CD"); modelo31 . agregarCaracteristica(" Direccion Asistida "); marca1 .agregarModelo( modelo11 ); marca1 .agregarModelo( modelo21 ); marca1 .agregarModelo( modelo31 ); Marca marca2 = new Marca("Toyota "); Modelo modelo12 = new Modelo ("Hilux", 2008 , 2); modelo12 . agregarCaracteristica("4x4"); modelo12 . agregarCaracteristica("Llantas "); modelo12 . agregarCaracteristica("Radio CD"); modelo12 . agregarCaracteristica("Mecanico "); modelo12 . agregarCaracteristica(" Neblineros"); modelo12 . agregarCaracteristica(" Direccion Asistida "); modelo12 . agregarCaracteristica("Aire Acondicionado"); modelo12 . agregarCaracteristica("Air Bag"); Modelo modelo22 = new Modelo ("Yaris", 2007 , 0); modelo22 . agregarCaracteristica("Alarma "); modelo22 . agregarCaracteristica("Aire Acondicionado"); modelo22 . agregarCaracteristica("Radio CD"); modelo22 . agregarCaracteristica("Mecanico "); modelo22 . agregarCaracteristica(" Alzavidrios Electricos"); modelo22 . agregarCaracteristica(" Direccion Asistida "); Modelo modelo32 = new Modelo ("Auris", 2008 , 1); modelo32 . agregarCaracteristica(" Neblineros"); modelo32 . agregarCaracteristica(" Alzavidrios Electricos"); modelo32 . agregarCaracteristica("Air Bag"); modelo32 . agregarCaracteristica(" Automatico"); modelo32 . agregarCaracteristica("Radio CD"); Modelo modelo42 = new Modelo ("Corolla ", 2006 , 0); modelo42 . agregarCaracteristica("Radio CD"); modelo42 . agregarCaracteristica("Alarma "); modelo42 . agregarCaracteristica(" Automatico"); modelo42 . agregarCaracteristica("Tapiz de cuero"); modelo42 . agregarCaracteristica(" Alzavidrios Electricos"); modelo42 . agregarCaracteristica("Aire Acondicionado"); modelo42 . agregarCaracteristica(" Neblineros"); modelo42 . agregarCaracteristica("Air Bag"); modelo42 . agregarCaracteristica(" Direccion Asistida "); Modelo modelo52 = new Modelo ("Yaris Sport", 2008 , 1); modelo52 . agregarCaracteristica("Radio CD"); modelo52 . agregarCaracteristica(" Alzavidrios Electricos"); marca2 .agregarModelo( modelo12 ); marca2 .agregarModelo( modelo22 ); marca2 .agregarModelo( modelo32 ); marca2 .agregarModelo( modelo42 ); if (! marca2 . agregarModelo(modelo52 )) { Usuario .mensajeConsola("No se pudo agregar el modelo " + modelo52 . getModelo() + " a la marca " + marca2 .getNombre()); IIC1103 – Cap´ıtulo 5: Strings 41
  • 42. } Marca marca3 = new Marca("Mercedes Benz"); Modelo modelo13 = new Modelo ("C 200 K", 2008 , 1); modelo13 . agregarCaracteristica("Llantas "); modelo13 . agregarCaracteristica("Radio CD"); modelo13 . agregarCaracteristica(" Alzavidrios Electricos"); modelo13 . agregarCaracteristica(" Automatico"); modelo13 . agregarCaracteristica(" Neblineros"); modelo13 . agregarCaracteristica("Alarma "); modelo13 . agregarCaracteristica("Tapiz de cuero"); modelo13 . agregarCaracteristica("Air Bag"); modelo13 . agregarCaracteristica(" Direccion Asistida "); modelo13 . agregarCaracteristica("Aire Acondicionado"); Modelo modelo23 = new Modelo ("CLK 500", 2008 , 2); modelo23 . agregarCaracteristica("Mecanico "); modelo23 . agregarCaracteristica("Alarma "); modelo23 . agregarCaracteristica("Air Bag"); modelo23 . agregarCaracteristica(" Alzavidrios Eletricos"); modelo23 . agregarCaracteristica(" Neblineros"); modelo23 . agregarCaracteristica("Llantas "); modelo23 . agregarCaracteristica(" Direccion Asistida "); modelo23 . agregarCaracteristica("4x4"); modelo23 . agregarCaracteristica("Radio CD"); modelo23 . agregarCaracteristica("Aire Acondicionado"); marca3 .agregarModelo( modelo13 ); marca3 .agregarModelo( modelo23 ); /** Incremento 2 */ // Mostramos el catalogo completo de cada marca marca1 .imprimirCatalogo(0); marca2 .imprimirCatalogo(0); marca3 .imprimirCatalogo(0); Usuario .mensajeConsola(""); // Mostramos la cantidad de modelos del anio 2008 que oferta cada marca Usuario .mensajeConsola("La marca " + marca1 . getNombre() + " tiene " + marca1 . autosDelAnio(2008) + " modelos anio 2008 en su catalogo ."); Usuario .mensajeConsola("La marca " + marca2 . getNombre() + " tiene " + marca2 . autosDelAnio(2008) + " modelos anio 2008 en su catalogo ."); Usuario .mensajeConsola("La marca " + marca3 . getNombre() + " tiene " + marca3 . autosDelAnio(2008) + " modelos anio 2008 en su catalogo ."); /** Incremento 3 */ // Mostramos el catalogo de cada marca solo con los modelos del anio // preferido int anio = Usuario .entero (" Ingrese el anio para el que desea revisar los modelos :"); marca1 .imprimirCatalogo(anio ); marca2 .imprimirCatalogo(anio ); marca3 .imprimirCatalogo(anio ); Usuario .mensajeConsola(""); // Ahora mostramos la cantidad de autos que tienen aire acondicionado Usuario .mensajeConsola("La marca " + marca1 .getNombre() + " tiene " + marca1 . modelosConCaracteristica("Aire acondicionado") + " modelos de automoviles con aire acondicionado en su catalogo ."); Usuario .mensajeConsola("La marca " + marca2 .getNombre() + " tiene " + marca2 . modelosConCaracteristica("Aire acondicionado") + " modelos de automoviles con aire acondicionado en su catalogo ."); Usuario .mensajeConsola("La marca " + marca3 .getNombre() + " tiene " + marca3 . modelosConCaracteristica("Aire acondicionado") + " modelos de automoviles con aire acondicionado en su catalogo .n"); // Finalmente mostramos la cantidad de autos tipo sedan que tienen aire // acondicionado Usuario .mensajeConsola("La marca " + marca1 .getNombre() + " tiene " + marca1 . modelosConCaracteristicaPorTipo("Aire acondicionado", 0) IIC1103 – Cap´ıtulo 5: Strings 42
  • 43. + " modelos de automoviles tipo sedan con aire acondicionado en su catalogo ."); Usuario .mensajeConsola("La marca " + marca2 . getNombre() + " tiene " + marca2 . modelosConCaracteristicaPorTipo("Aire acondicionado", 0) + " modelos de automoviles tipo sedan con aire acondicionado en su catalogo ."); Usuario .mensajeConsola("La marca "+ marca3 . getNombre() + " tiene " + marca3 . modelosConCaracteristicaPorTipo("Aire acondicionado", 0) + " modelos de automoviles tipo sedan con aire acondicionado en su catalogo ."); } } Criterios de soluci´on Clase Modelo • Atributos: Declaramos los atributos necesarios seg´un nos indican en el enunciado: dos String, uno para el nombre y otro para las caracter´ısticas y dos enteros, uno para representar el a˜no y otro para representar el tipo (camioneta, sed´an, etc) • Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametros el nombre, el a˜no y el tipo y los asigna a los atributos correspondientes. • M´etodo agragarCaracteristica: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro un String con la caracter´ıstica a agregar y tenemos que concatenarlo al String que almacena las caracter´ısticas. • Getters: Seg´un el uso dado en la clase Principal necesitamos 3 m´etodos get para obtener el nombre del modelo, el a˜no y el tipo. • M´etodo tieneCaracteristica: Este m´etodo sirve para revisar si el modelo tiene una determinada caracter´ıstica (para cumplir con lo pedido en el incremento 3), puede hacerse tambi´en s´olo en la clase Marca. Lo que hacemos es buscar la caracter´ıstica generando todos los substrings desde la lista de caracter´ısticas que tengan el mismo largo que la caracter´ıstica recibida y comparar hasta encontrar alguna coincidencia. • M´etodo mostrar: Revisamos el tipo y seg´un eso mostramos en Consola el nombre del modelo, su a˜no seguido de ’Sed´an’, ’Station Wagon’ o ’Camioneta’, seg´un corresponda. Clase Marca: • Atributos: Declaramos los atributos necesarios seg´un lo que se nos indica en el enunciado: un String para guardar el nombre y cuatro objetos de la clase Modelo que representen a los modelos de auto que tiene la Marca. • Constructor: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro un String con el nombre de la marca y lo asigna al atributo correspondiente. • M´etodo agregarModelo: Lo declaramos seg´un el uso mostrado en la clase Principal. Recibe como par´ametro un objeto de la clase Modelo. Tenemos que revisar a qu´e objeto, de los 4 que tenemos como atributos, debemos asignarlo, revisando cu´al de ellos es todav´ıa null. Retornamos true o false seg´un se pudo o no asignar el modelo. • M´etodo getNombre: Retorna el nombre de la marca. • M´etodo autosDelAnio: Recorremos todos los modelos y obtenemos su a˜no (cuidando que el objeto no sea null) y lo comparamos con el a˜no recibido como par´ametro. Retornamos el n´umero de veces que la comparaci´on fue exitosa. • M´etodo imprimirCatalogo: Mostramos en la consola el nombre de la marca y el n´umero de autos del a˜no (seg´un el par´ametro recibido) llamando al m´etodo autosDelAnio. Luego, por cada Modelo llamamos al m´etodo que muestra su nombre y su tipo. • M´etodo modelosConCaracteristica: Para no implementar un m´etodo dos veces simplemente llamamos al m´etodo modelosConCaracteristicaPorTipo definiendo un valor inv´alido para el tipo. IIC1103 – Cap´ıtulo 5: Strings 43
  • 44. • M´etodo modelosConCaracteristicaPorTipo: Recorremos todos los modelos y en cada uno revi- samos que no sea nulo y que tenga la caracter´ıstica solicitada (llamando al m´etodo que implemen- tamos en la clase Modelo). Adem´as, en caso que el tipo sea v´alido, tambi´en revisamos que el tipo del modelo corresponda. Si se cumplen ambas condiciones aumentamos el contador de modelos, el cual retornamos al finalizar el m´etodo. Posible soluci´on import iic1103Package.*; public class Marca { // Definimos los atributos necesarios private String nombre ; // Definimos los modelos de auto que tiene la Marca private Modelo modelo0 ; private Modelo modelo1 ; private Modelo modelo2 ; private Modelo modelo3 ; public Marca(String nombre ) { this. nombre = nombre ; } public Modelo obtenerModelo(int indice ) { // Obtenemos el modelo segun su indice if ( indice == 0) { return modelo0 ; } else if (indice == 1) { return modelo1 ; } else if (indice == 2) { return modelo2 ; } else { return modelo3 ; } } public boolean agregarModelo(Modelo modelo ) { // Para agregar una nueva marca , buscamos el primero de los atributos // que aun sea nulo if ( modelo0 == null) { modelo0 = modelo ; } else if (modelo1 == null) { modelo1 = modelo ; } else if (modelo2 == null) { modelo2 = modelo ; } else if (modelo3 == null) { modelo3 = modelo ; } else { // Si no hay ninguno vacio entonces retornamos false return false; } return true; } public int autosDelAnio(int anio) { // Declaramos una variable para contar , y recorremos los modelos // buscando aquellos que coincidan con el anio int contador = 0; for (int i = 0; i < 4; i++) { Modelo modelo = obtenerModelo(i); if (modelo != null && modelo .getAnio () == anio) { contador ++; } } return contador ; } public int modelosConCaracteristica(String caracteristica) { // Llamamos al metodo que busca tambien por tipo de auto , definiendo un // valor invalido para dicho parametro return modelosConCaracteristicaPorTipo( caracteristica , -1); } IIC1103 – Cap´ıtulo 5: Strings 44