sábado, 29 de junio de 2013

Flujos ObjectInputStream Java

Los objetos guardados en archivos con flujos de la clase ObjectOutputStream se recuperan, se
leen, con flujos de entrada del tipo ObjectInputStream. Esta clase es una extensión de InputStream,
además implementa la interfaz DataInput; por ello dispone de los diversos métodos de entrada
(read) para cada uno de los tipos de datos, readInt( )… El método más interesante definido
por la clase ObjectInputStream es readObject( ); lee un objeto del flujo de entrada (del archivo
asociado al flujo de bajo nivel). Este objeto se escribió en su momento con el método writeObject(
).
public Object readObject( ) throws IOException;
El constructor de flujos ObjectInputStream tiene como entrada otro flujo, de bajo nivel, de
cualquier tipo derivado de InputStream, por ejemplo FileInputStream, asociado con el archivo
de objetos. A continuación se crea un flujo de entrada para leer los objetos del archivo "archivoObjets.
dat":
ObjectInputStream obje = new ObjectInputStream(
new FileInputStream("archivoObjets.dat "));
El constructor levanta una excepción si, por ejemplo, el archivo no existe,..., del tipo ClassNotFoundException,
o bien IOException; es necesario poder capturar estas excepciones.




EJEMPLO PRACTICO:


Se desea guardar en un archivo los libros y discos de que disponemos. Los datos de interés para un
libro son: título, autor, editorial, número de páginas; para un disco: cantante, título, duración en minutos,
número de canciones y precio.
Se podría diseñar una jerarquía de clases que modelase los objetos libro, disco,… Sin embargo, el
ejercicio sólo pretende mostrar cómo crear objetos persistentes; declara directamente la clase Libro
y Disco con la propiedad de ser “serializables” (implementan la interfaz java.io.Serializable).
La clase principal crea un flujo de salida para objetos; según los datos que introduce el usuario se instancia
un tipo de objeto Disco o Libro y con el método writeObject( ) se escribe en el flujo.


import java.io.*;
class Libro implements Serializable
{
private String titulo;
private String autor;
private String editorial;
private int pagina;
public Libro( )
{
titulo = autor = editorial = null;
}
public Libro(String t, String a, String e, int pg)
{
titulo = t;
autor = a;
editorial = e;
pagina = pg;
}
public void entrada(BufferedReader ent) throws IOException
{
System.out.print("Titulo: "); titulo = ent.readLine( );
System.out.print("Autor: "); autor = ent.readLine( );
System.out.print("Editorial: "); editorial = ent.readLine( );
System.out.print("Páginas: ");
pagina = Integer.parseInt(ent.readLine( ));
}
}


class Disco implements Serializable
{
private String artista;
private String titulo;
private int numCancion, duracion;
private transient double precio;
public Disco( )
{
artista = titulo = null;
}
public Disco(String a, String t, int n, int d, double p)
{
titulo = t;
artista = a;
numCancion = n;
duracion = d;
precio = p;
}
public void entrada(BufferedReader ent) throws IOException
{
System.out.print("Cantante: "); artista = ent.readLine( );
System.out.print("Titulo: "); titulo = ent.readLine( );


System.out.print("Canciones: ");
numCancion = Integer.parseInt(ent.readLine( ));
System.out.print("Duración(minutos): ");
duracion = Integer.parseInt(ent.readLine( ));
System.out.print("Precio: ");
precio = Double.valueOf(ent.readLine( )).doubleValue( );
}
}
public class Libreria
{
public static void main (String [ ] a)
{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
File mf = new File("libreria.dat");
ObjectOutputStream fobj = null;
Libro libro = new Libro( );
Disco disco = new Disco( );
int tipo;
boolean mas = true;
try {
fobj = new ObjectOutputStream(new FileOutputStream(mf));
do {
System.out.println
("Pulsa L(libro), D(disco), F(finalizar)");
tipo = System.in.read( );
System.in.skip(2); // salta caracteres fin de línea
switch (tipo) {
case 'L':

case 'l': libro = new Libro( );
libro.entrada(br);
fobj.writeObject(libro);
break;
case 'D':
case 'd': disco = new Disco( );
disco.entrada(br);
fobj.writeObject(disco);
break;
case 'F':
case 'f': fobj.close( );
mas = false;
}
} while (mas);
}
catch (IOException e)
{
e.printStackTrace( );
}
}
}




BufferedReader Java

La lectura de archivos de texto se realiza con un flujo que almacena los caracteres en un búfer intermedio.
Los caracteres no se leen directamente del archivo sino del búfer; con esto se consigue más
eficiencia en las operaciones de entrada. La clase BufferReader permite crear flujos de caracteres
con búfer, es una forma de organizar el flujo básico de caracteres del que procede el texto; esto se
manifiesta
en que al crear el flujo BufferReader se inicializa con un flujo de caracteres de tipo
InputStreamReader.


El constructor de la clase tiene un argumento de tipo Reader, un FileReader o un InputStreamReader.
El flujo creado dispone de un búfer de un tamaño, normalmente suficiente; el tamaño
del búfer se puede especificar en el constructor con un segundo argumento aunque no resulta
necesario. Ejemplos de flujos con búfer:
File mf = new File("C:\listados.txt");
FileReader fr = new FileReader(mf);
BufferedReader bra = new BufferedReader(fr);
File mfz = new File("Complejo.dat");
BufferedReader brz = new BufferedReader(
new InputStreamReader(
new FileInputStream(mfz)));

La clase BufferedReader deriva directamente de la clase Reader. Entonces, dispone de los
métodos read( ) para leer un carácter, o bien un arreglo de caracteres. El método más importante es
readLine( ):
public String readLine( ) throws IOException;
El método lee una línea de caracteres, termina con el carácter de fin de línea, y devuelve una cadena
con la línea leída (no incluye el carácter fin de línea). Puede devolver null si lee la marca de fin
de archivo.


Otro método interesante es close( ), cierra el flujo y libera los recursos asignados. El fin de la
aplicación Java también cierra los flujos abiertos, aunque es recomendable cerrar un flujo que no se
va a utilizar.
public void close( ) throws IOException




Flujos PrintStream Java

La clase PrintStream deriva directamente de FilterOutputStream. La característica más importante
es que dispone de métodos que añaden la marca de fin de línea. Los flujos de tipo PrintStream
son de salida, se asocian con otro flujo de bajo nivel, de bytes, que a su vez se crea asociado a un archivo
externo. Por ejemplo, mediante el flujo fjp se puede escribir cualquier tipo de dato; los bytes
que ocupa cada dato se vuelcan secuencialmente en Complex.dat
fjp = new PrintStream(new FileOutputStream("Complex.dat"));
Los métodos de esta clase, print( ) y println( ) están sobrecargados para poder escribir
desde cadenas hasta cualquiera de los datos primitivos; println( ) escribe un dato y a continuación
añade la marca de fin de línea.
A continuación están los métodos más importantes:
public PrintStream(OutputStream destino)
Crea un objeto asociado con cualquier objeto de salida pasado como argumento.
public PrintStream(OutputStream destino, boolean flag)
Crea un objeto asociado con objeto de salida pasado como argumento y si el segundo argumento
es true se produce un automático volcado al escribir el fin de línea.
public void flush( )
Vuelca el flujo actual.


public void print(Object obj)
Escribe la representación del objeto obj en el flujo.
public void print(String cad)
Escribe la cadena en el flujo.
public void print(char c)
Escribe el carácter c en el flujo.
método print( ) para cada tipo de dato primitivo.
public void println(Object obj)
Escribe la representación del objeto obj en el flujo y el fin de línea.
public void println(String cad)
Escribe la cadena en el flujo y el fin de línea.
catch (IOException io)
{
System.out.println("Anomalía al leer flujo de entrada, "
+ io.getMessage( ));
return; // termina la ejecución
}
finally {
try
{
obfl.close( );
}
catch (IOException er)
{
er.printStackTrace( );
}
}
// termina el proceso, escribe la temperatura máxima
System.out.println("\n La temperatura máxima: " + (float)mxt);
}
}


public void println(char c)
Escribe el carácter c en el flujo y el fin de línea.
método println( ) para cada tipo de dato primitivo


Nota de programación
El objeto definido en la clase System: System.out es de tipo PrintStream, asociado,
normalmente, con la pantalla. Por ello se han utilizado los métodos:
System.out.print( );
System.out.println( );

Archivos y flujos en Java

Los archivos tienen como finalidad guardar datos de forma permanente; una vez que acaba la aplicación,
los datos siguen disponibles para que otra aplicación pueda recuperarlos, para su consulta o modificación.
El proceso de archivos en Java se hace mediante el concepto de flujo (stream) o canal, o también
denominado secuencia. Los flujos pueden estar abiertos o cerrados, conducen los datos entre el programa
y los dispositivos externos. Con las clases y sus métodos proporcionados por el paquete java.io
se pueden tratar archivos secuenciales, de acceso directo, archivos indexados, etcétera.


Flujos y archivos

Un fichero (archivo) de datos, o simplemente un archivo, es una colección de registros relacionados
entre sí con aspectos en común y organizados para un propósito específico. Por ejemplo, un fichero
de una clase escolar contiene un conjunto de registros de los estudiantes de esa clase.
Un archivo en una computadora es una estructura diseñada para contener datos, los cuales están
organizados de tal modo que puedan ser recuperados fácilmente, actualizados o borrados y almacenados
de nuevo en el archivo con todos los cambios realizados.
Según las características del soporte empleado y el modo en que se han organizado los registros,
se consideran dos tipos de acceso a los registros de un archivo:
• acceso secuencial,
• acceso directo.

El acceso secuencial implica el acceso a un archivo según el orden de almacenamiento de sus registros,
uno tras otro.
El acceso directo implica el acceso a un registro determinado, sin que ello implique la consulta de
los registros precedentes. Este tipo de acceso sólo es posible con soportes direccionales.
En Java un archivo es, sencillamente, una secuencia de bytes, que son la representación de los datos
almacenados. Java dispone de clases para trabajar las secuencias de bytes como datos de tipos básicos
(int, double, String ...); incluso, para escribir o leer del archivo objetos. El diseño del archivo es el
que establece la forma de manejar las secuencias de bytes, con una organización secuencial, o bien de
acceso directo.
Un flujo (stream) es una abstracción que se refiere a una corriente de datos que fluyen entre un
origen o fuente (productor) y un destino o sumidero (consumidor). Entre el origen y el destino debe
existir una conexión o canal ( pipe) por la que circulen los datos. La apertura de un archivo supone establecer
la conexión del programa con el dispositivo que contiene el archivo; por el canal que comunica
el archivo con el programa van a fluir las secuencias de datos.
Abrir un archivo supone crear un objeto que queda asociado con un flujo. Al comenzar la ejecución
de un programa Java se crean automáticamente tres objetos de flujo, son tres canales por los que
pueden fluir datos, de entrada o de salida. Éstos son objetos definidos en la clase System:



• System.in; entrada estándar; permite la entrada al programa de flujos de bytes desde el teclado.
• System.out; salida estándar; permite al programa la salida de datos por pantalla.
• System.err; salida estándar de errores; permite al programa salida de errores por pantalla.
En Java, un archivo es simplemente un flujo externo, una secuencia de bytes almacenados en un
dispositivo externo (normalmente en disco). Si el archivo se abre para salida, es un flujo de archivo de
salida. Si el archivo se abre para entrada, es un flujo de archivo de entrada. Los programas leen o
escriben
en el flujo, que puede estar conectado a un dispositivo o a otro. El flujo es por tanto una abstracción
de tal forma que las operaciones que realizan los programas son sobre el flujo independientemente
del dispositivo al que esté asociado.


A tener en cuenta
El paquete java.io agrupa al conjunto de clases e interfaces necesarios para procesar archivos.
Es necesario utilizar clases de este paquete; por consiguiente, se debe incorporar al programa
con la sentencia import java.io.*.

Información de un archivo
Con los métodos de la clase File se obtiene información relativa al archivo o ruta con que se ha inicializado
el objeto. Así, antes de crear un flujo para leer de un archivo es conveniente determinar si el
archivo existe; en caso contrario no se puede crear el flujo. A continuación se exponen los métodos
más útiles para conocer los atributos de un archivo o un directorio.
public boolean exists( )
Devuelve true si existe el archivo (o el directorio).
public boolean canWrite( )
Devuelve true si se puede escribir en el archivo, si no es de sólo lectura.
public boolean canRead( )
Devuelve true si es de sólo lectura.
public boolean isFile( )
Devuelve true si es un archivo.
public boolean isDirectory( )
Devuelve true si el objeto representa a un directorio.
public boolean isAbsolute( )
Devuelve true si el directorio es la ruta completa.
public long length( )
Devuelve el número de bytes que ocupa el archivo. Si el objeto es un directorio devuelve cero.


public long lastModified( )
Devuelve la hora de la última modificación. El número devuelto es una representación interna
de la hora, minutos y segundos de la última modificación, sólo es útil para establecer
comparaciones con otros valores devueltos por el mismo método.
También dispone de métodos que modifican el archivo: cambiar de nombre, marcar de sólo lectura.
Para los directorios, tiene métodos para crear uno nuevo, obtener una lista de todos los elementos
(archivos o subdirectorios) del directorio. Algunos de estos métodos se escriben a continuación.
public String getName( )
Devuelve una cadena con el nombre del archivo o del directorio con que se ha inicializado
el objeto.
public String getPath( )
Devuelve una cadena con la ruta relativa al directorio actual.
public String getAbsolutePath( )
Devuelve una cadena con la ruta completa del archivo o directorio.
public boolean setReadOnly( )
Marca al archivo para que no se pueda escribir, de sólo lectura.
public boolean delete( )
Elimina el archivo o directorio (debe estar vacío).
public boolean renameTo(File nuevo)
Cambia el nombre del archivo con que ha sido inicializado el objeto por el nombre que contiene
el objeto pasado como argumento.
public boolean mkdir( )

Crea el directorio con el que se ha creado el objeto.
public String[ ] list( )
Devuelve un array de cadenas, cada una contiene un elemento (archivo o directorio) del directorio
con el que se ha inicializado el objeto.





viernes, 28 de junio de 2013

Declaración de un tipo parametrizado


Al nombre de la colección le sigue el tipo de los elementos entre paréntesis angulares (< tipo>):
Coleccion<tipo> v;
Si se parametrizan dos tipos, como ocurre con los mapas, se separan con coma:
Coleccion<tipoClave,tipoValor> cc;
Por ejemplo:
Stack<Double> pila;
SortedMap<Integer,String> mapa;
Realmente con el tipo parametrizado es como si se hubiera declarado otra clase, en consecuencia
las instancias de colecciones parametrizadas se crean con esa clase, es decir new
Coleccion<tipo> crea la instancia. Por ejemplo:
pila = newStack<Double>();
mapa = newTreeMap<Integer,String>();

Constantes Php

Usar constantes
Hasta ahora el capítulo se ha concentrado en las variables, que son útiles para almacenar y
cambiar valores durante el tiempo de vida del script PHP. Pero, ¿qué sucede si necesitas almacenar
un valor fijo, que permanezca estático durante el curso del script? Bien, en esos casos se
debe utilizar una constante.
Como su nombre lo sugiere, las constantes son contenedores de PHP para valores que
permanecen constantes y que nunca cambian. Por lo regular se utilizan para valores bien
conocidos de antemano y que son utilizados, sin cambio alguno, en diferentes lugares de la
aplicación. Buenos candidatos para constantes son los niveles de depuración y registro, los
números de versión, las marcas de configuración y las fórmulas.
Las constantes se definen en PHP con la función define(), la cual acepta dos argumentos:
el nombre de la constante y su valor. Los nombres de las constantes deben seguir las
mismas reglas que las variables, con una sola excepción: el prefijo $ no se requiere para los
nombres de constantes.
He aquí un ejemplo para definir y utilizar una constante dentro de un script:
<?php
// define constantes
define('PROGRAMA', 'The Matrix');
define('VERSION', 11.7);
// usar constantes
// datos de salida: 'Bienvenido a The Matrix (versión 11.7)'
echo 'Bienvenido a ' . PROGRAMA . ' (versión ' . VERSION . ')';
?>

Pedir un número entre 0 y 9.999 y decir cuantas cifras tiene

package bol01ej11;
public class Main {
public static void main(String[] args) {
int num;
System.out.print("Introduzca un número entre 0 y 99.999: ");
num=Entrada.entero();
if(num<10)
System.out.println("tiene 1 cifra");
else{
if(num<100)
System.out.println("tiene 2 cifras");
else{
if(num<1000)
System.out.println("tiene 3 cifras");
else{
if(num<10000)
System.out.println("tiene 4 cifras");
else{
if(num<100000)
System.out.println("tiene 5 cifras");
}
}
}
}
}

Pedir tres números y mostrarlos ordenados de mayor a menor.

package bol01ej10;
public class Main {
public static void main(String[] args) {
int a,b,c;
System.out.print("Introduzca primer número: ");
a=Entrada.entero();
System.out.print("Introduzca segundo número: ");
b=Entrada.entero();
System.out.print("Introduzca tercer número: ");
c=Entrada.entero();
if(a>b && b>c)
System.out.println( a+", "+b+", "+c);
else{
if(a>c && c>b)
System.out.println(a+", "+c+", "+b);
else{
if(b>a && a>c)
System.out.println(b+", "+a+", "+c);
else{
if(b>c && c>a)
System.out.println(b+", "+c+", "+a);
else{
if(c>a && a>b)
System.out.println(c+", "+a+", "+b);
else{
if(c>b && b>a)
System.out.println(c+", "+b+", "+a);
}
}
}
}
}
}
}

Pedir dos números y decir cual es el mayor o si son iguales.

package bol01ej08;
public class Main {
public static void main(String[] args) {
int n1,n2;
System.out.print("Introduce un número: ");
n1=Entrada.entero();
System.out.print("Introduce otro número: ");
n2=Entrada.entero();
if(n1==n2)
System.out.println("Son iguales");
else
{
if(n1>n2)
System.out.println(n1 + " es mayor que " + n2);
else
System.out.println(n2 + " es mayor que " + n1);
}
}
}

Pedir dos números y decir cual es el mayor.

package bol01ej07;
public class Main {
public static void main(String[] args) {
int n1,n2;
System.out.print("Introduce un número: ");
n1=Entrada.entero();
System.out.print("Introduce otro número: ");
n2=Entrada.entero();
// si ambos números son iguales diría que n2 es mayor que n1
if(n1>n2)
System.out.println(n1 + " es mayor que " + n2);
else
System.out.println(n2 + " es mayor que " + n1);
}
}

Pedir dos números y decir si uno es múltiplo del otro

package bol01ej06;
public class Main {
public static void main(String[] args) {
int n1,n2;
System.out.print("Introduce un número: ");
n1=Entrada.entero();
System.out.print("Introduce otro número: ");
n2=Entrada.entero();
if(n1%n2==0)
System.out.println("Son múltiplos");
else
System.out.println("No son múltiplos");
}
}

Pedir dos números y decir si son iguales o no. Java

package bol01ej04;
public class Main {
public static void main(String[] args) {
int n1,n2;
System.out.print("Introduce un número: ");
n1=Entrada.entero();
System.out.print("Introduce otro número: ");
n2=Entrada.entero();
if(n1==n2)
System.out.println("Son iguales");
else
System.out.println("No son iguales");
}
}

jueves, 27 de junio de 2013

Características únicas e PHP

Si estás familiarizado con otros lenguajes que se ejecutan del lado del servidor, como ASP.
NET o JSP, tal vez te preguntes qué tiene de especial PHP o qué lo hace tan diferente de esas
opciones competidoras. Bien, he aquí algunas razones:
Rendimiento Los scripts escritos en PHP se ejecutan más rápido que los escritos en otros
lenguajes de creación de scripts; numerosos estudios comparativos independientes ponen
este lenguaje por encima de sus competidores como JSP, ASP.NET y Perl. El motor de PHP

5.0 fue completamente rediseñado con un manejo óptimo de memoria para mejorar su rendimiento
y es claramente más veloz que las versiones previas. Además, están disponibles aceleradores
de terceros que pueden mejorar aún más el rendimiento y el tiempo de respuesta.
Portabilidad PHP está disponible para UNIX, Microsoft Windows, Mac OS y OS/2 y los
programas escritos en PHP se pueden transportar de una plataforma a otra. Como resultado,
las aplicaciones PHP desarrolladas en Windows, por ejemplo, se ejecutarán en UNIX sin
grandes contratiempos. Esta capacidad de desarrollar fácilmente para múltiples plataformas es
muy valiosa, en especial cuando se trabaja en un ambiente corporativo de varias plataformas o
cuando se intenta atacar diversos sectores del mercado.

Fácil de usar “La sencillez es la mayor sofisticación”, dijo Leonardo da Vinci y, de acuerdo
con ello, PHP es un lenguaje de programación extremadamente sofisticado. Su sintaxis es
clara y consistente y viene con una documentación exhaustiva para las más de 5 000 funciones
incluidas en la distribución principal. Esto reduce de manera importante la curva de aprendizaje
tanto para los desarrolladores novatos como para los expertos, y es una de las razones por
las que PHP es favorecido como una herramienta rápida para la creación de prototipos que
permitan el desarrollo de aplicaciones basadas en Web.

Código libre PHP es un proyecto de código libre; el lenguaje es desarrollado por un grupo
de programadores voluntarios distribuidos por todo el mundo, quienes ponen a disposición
gratuita el código fuente a través de Internet, y puede ser utilizado sin costo, sin pagos por licencia
y sin necesidad de grandes inversiones en equipo de cómputo ni programas. Con ello se
reduce el costo del desarrollo de programas sin afectar la flexibilidad ni la confiabilidad de los
productos. La naturaleza del código libre implica que cualquier desarrollador, dondequiera que
se encuentre, puede inspeccionar el árbol de código, detectar errores y sugerir posibles correcciones;
con esto se produce un producto estable y robusto, en que las fallas, una vez descubiertas,
se corrigen rápidamente, en algunas ocasiones, ¡horas después de ser descubiertas!
Soporte comunitario Una de las mejores características de los lenguajes a los que da soporte
una comunidad, como PHP, es el acceso que ofrece a la creatividad e imaginación de
cientos de desarrolladores ubicados en diferentes partes del mundo. En la comunidad PHP, los
frutos de esta creatividad pueden ser encontrados en PEAR (PHP Extension and Application
Repository), el repositorio de extensiones y aplicaciones de PHP (http://pear.php.net), y en
PECL (PHP Extension Community Library), la biblioteca de la comunidad de extensiones
PHP (http://pecl.php.net), que contienen cientos de soluciones y extensiones que los desarrolladores
pueden ocupar para añadir sin esfuerzo nuevas funcionalidades a sus aplicaciones
PHP. Utilizar estas soluciones suele ser una mejor opción en tiempo y costo, en vez de desarrollar
desde cero tu propio código.

Soporte a aplicaciones de terceros Una de las fortalezas históricas de PHP ha sido su
soporte a una amplia gama de diferentes bases de datos, entre las cuales se incluyen MySQL,

PostgreSQL, Oracle y Microsoft SQL Server. PHP 5.3 soporta más de quince diferentes motores
de bases de datos, e incluye una API (interfaz de programación de aplicaciones) común
para el acceso a base de datos. El soporte para XML facilita la lectura (y escritura) de documentos
XML como si fueran estructuras de datos nativas de PHP; es posible accesar a colecciones
de nodos XML utilizando XPath y transformar código XML en otros formatos con las
hojas de estilo XSLT.

Y no termina aquí. La arquitectura extensible de PHP permite que los desarrolladores
escriban sus propias adiciones personalizadas al lenguaje, de manera que hoy en día los desarrolladores
de PHP pueden hacer que sus aplicaciones lean y registren imágenes en formato
GIF, JPEG y PNG; enviar y recibir correos electrónicos utilizando protocolos SMTP, IMAP y
POP3; colaborar con servicios Web utilizando protocolos SOAP y REST; validar datos de entrada
utilizando expresiones regulares de Perl, además de crear y manipular documentos PDF.
Más aún, PHP puede acceder a las bibliotecas de C, las clases de Java y los objetos COM, ¡y
aprovechar el código escrito en esos lenguajes!

Algoritmo de las 8 reinas en Java

public boolean solucionReinas()
{
solucion = false;
ponerReina(1);
return solucion;
} private void ponerReina(int i)
{
int j;
j = 0; // inicializa posibles movimientos
do {
j++;
reinas[i] = j; // prueba a colocar reina i en fila j,
// a la vez queda anotado el movimiento
if (valido(i))
{
if (i < N) // no completado el problema


{
ponerReina(i+1);
// vuelta atrás
if (!solucion)
reinas[i] = 0;
}
else // todas las reinas colocadas
solucion = true;
}
} while(!solucion && (j < 8));
}
private boolean valido(int i)
{
/* Inspecciona si la reina de la columna i es atacada por
alguna reina colocada anteriormente */
int r;
boolean libre;
libre = true;
for (r = 1; r <= i-1; r++)
{
// no esté en la misma fila
libre = libre && (reinas[i] != reinas[r]);
// no esté en alguna de las dos diagonales
libre = libre && ((i + reinas[i]) != (r + reinas[r]));
libre = libre && ((i - reinas[i]) != (r - reinas[r]));
}

Recursion infinita

La iteración y la recursión pueden producirse infinitamente. Un bucle infinito ocurre si la prueba
o test de continuación de bucle nunca se vuelve falsa; una recursión infinita ocurre si la etapa
de recursión no reduce el problema en cada ocasión, de modo que converja sobre el caso base o
condición de salida.


La recursión infinita significa que cada llamada recursiva produce otra llamada recursiva
y ésta, a su vez, otra llamada recursiva, y así para siempre. En la práctica, dicho método se
ejecutará hasta que la computadora agote la memoria disponible y se produzca una terminación
anormal del programa.
El flujo de control de un método recursivo requiere tres condiciones para una terminación
normal:
• Un test para detener (o continuar) la recursión (condición de salida o caso base).
• Una llamada recursiva (para continuar la recursión).
• Un caso final para terminar la recursión.




¿Que es mejor la recursion o iteracion?

Se han estudiado varios métodos que se pueden implementar fácilmente, bien de modo recursivo,
bien de modo iterativo. En esta sección se comparan los dos enfoques y se examinan las razones
por las que el programador puede elegir un enfoque u otro según la situación específica.
Tanto la iteración como la recursión se basan en una estructura de control: la iteración utiliza
una estructura repetitiva y la recursión utiliza una estructura de selección. Tanto la iteración
como la recursión implican repetición: la iteración utiliza explícitamente una estructura repetitiva
mientras que la recursión consigue la repetición mediante llamadas repetidas al método.
La iteración y la recursión implican cada una un test de terminación (condición de parada). La
iteración termina cuando la condición del bucle no se cumple, mientras que la recursión termina
cuando se reconoce un caso base o se alcanza la condición de parada.
La recursión tiene muchas desventajas. Se invoca repetidamente al mecanismo de llamadas a
métodos y, en consecuencia, se necesita un tiempo suplementario para realizar cada llamada.

Esta característica puede resultar cara en tiempo de procesador y espacio de memoria. Cada
llamada recursiva produce una nueva creación y copia de las variables de la función, esto consume
más memoria e incrementa el tiempo de ejecución. Por el contrario, la iteración se produce
dentro de un método, de modo que las operaciones suplementarias en la llamada al método y en
la asignación de memoria adicional son omitidas.
Entonces, ¿cuáles son las razones para elegir la recursión? La razón fundamental es que
existen numerosos problemas complejos que poseen naturaleza recursiva y, en consecuencia, son
más fáciles de implementar con algoritmos de este tipo. Sin embargo, en condiciones críticas de
tiempo y de memoria; es decir, cuando el consumo de tiempo y memoria sean decisivos o concluyentes
para la resolución del problema, la solución a elegir debe ser, normalmente, la iterativa.

Mostrar alfabeto en forma recursiva Java

public class Alfabeto
{
public static void main(String [] a)
{
System.out.println();
metodoA('Z');
System.out.println();
}
static void metodoA(char c)
{
if (c > 'A')

metodoB(c);
System.out.print(c);
}
static void metodoB(char c)
{
metodoA(--c);
}
}

Factorial Recursivo Java

import java.io.*;
public class Factorial
{
public static void main(String[] ar)throws IOException
{
int n;
BufferedReader entrada = new BufferedReader(
new InputStreamReader(System.in));
do {
System.out.print("Introduzca número n: ");
n = Integer.parseInt(entrada.readLine());
}while (n < 0);
System.out.println("\n \t" + n + "!= " + factorial(n));
}
static long factorial (int n)
{
if (n <= 1)
return 1;
else
{
long resultado = n * factorial(n - 1);
return resultado;
}
}
}

Implementar una interfaz en Java

La interfaz especifica el comportamiento común que tiene un conjunto de clases. Dicho comportamiento
se implementa en cada una de las clases, es lo que se entiende como implementación
de una interfaz. Se utiliza una sintaxis similar a la derivación o extensión de una clase, con la
palabra reservada implements en lugar de extends.
class NombreClase implements NombreInterfaz


{
// definición de atributos
// implementación de métodos de la clase
// implementación de métodos de la interfaz
}


La clase que implementa una interfaz tiene que especificar el código (la implementación) de
cada uno de los métodos de la interfaz. De no hacerlo la clase se convierte en clase abstracta y
entonces debe declararse abstract. Es una forma de obligar a que cada método de la interfaz
se implemente.

Considérese una jerarquía de barcos, todos tienen como comportamiento común msgeSocorro()
y alarma(). Las clases BarcoPasaje, PortaAvion y Pesquero implementan el comportamiento
común.
Se declara la interfaz Barco:
interface Barco
{
void alarma();
void msgeSocorro(String av);
}

Las clases BarcoPasaje, PortaAvion y Pesquero implementan la interfaz Barco y, además,
sus métodos:
class BarcoPasaje implements Barco
{
private int eslora;
private int numeroCamas = 101;
public BarcoPasaje()
{
System.out.println("Se crea objeto BarcoPasaje.");
}
public void alarma()
{
System.out.println("¡¡¡ Alarma del barco pasajero !!!");
}
public void msgeSocorro(String av)
{
alarma();
System.out.println("¡¡¡ SOS SOS !!!" + av);
}
}


class PortaAvion implements Barco
{
private int aviones = 19;
private int tripulacion;
public PortaAvion(int marinos)
{
tripulacion = marinos;
System.out.println("Se crea objeto PortaAviones.");
}
public void alarma()
{
System.out.println("¡¡¡ marineros a sus puestos !!!");
}
public void msgeSocorro(String av)
{
System.out.println("¡¡¡ SOS SOS !!! " + av);
}
} class Pesquero implements Barco
{


private int eslora;
private double potencia;
private int pescadores;
String nombre;
public Pesquero(int tripulacion)
{
pescadores = tripulacion;
System.out.println("Se crea objeto Barco Pesquero.");
}
public void alarma()
{
System.out.println("¡¡¡ Alarma desde el pesquero " +
nombre + " !!!");
}
public void msgeSocorro(String av)
{
System.out.println("¡¡¡ SOS SOS !!! " + av);
}
}

INTERFACES JAVA

Java incorpora una construcción del lenguaje, llamada interface, que permite declarar un
conjunto de constantes y de cabeceras de métodos abstractos. Estos deben implementarse en las
clases y constituyen su interfaz. En cierto modo, es una forma de declarar que todos los métodos
de una clase son públicos y abstractos, con lo que se especifica el comportamiento común de
todas las clases que implementen la interfaz.


La declaración de una interfaz es similar a la de una clase; en la cabecera se utiliza la palabra
reservada interface en vez de class, por ejemplo:


public interface NodoG
{
boolean igual(NodoG t);
NodoG asignar(NodoG t);
void escribir(NodoG t);
}
La interfaz NodoG define tres métodos abstractos y además públicos. Sin embargo no es necesario
especificar ni abstract ni public ya que todos los métodos de una interface lo son.

Sintaxis
acceso interface NombreInterface
{
constante1;
...
constanten;
tipo1 nombreMetodo1(argumentos);
...
tipon nombreMetodon (argumentos);

} acceso es la visibilidad de la interfaz definida, normalmente public.

Ventajas del polimorfismo Java

El polimorfismo hace su sistema más flexible sin perder ninguna de las ventajas de la compilación
estática de tipos que tienen lugar en tiempo de compilación. Este es el caso de Java.
Las aplicaciones más frecuentes del polimorfismo son:
• Especialización de clases derivadas. El uso más común del polimorfismo es derivar clases
especializadas de clases que han sido definidas. Así, por ejemplo, una clase Cuadrado es
una especialización de la clase Rectangulo (cualquier cuadrado es un tipo de rectángulo).
Esta clase de polimorfismo aumenta la eficiencia de la subclase, mientras conserva un alto
grado de flexibilidad y permite un medio uniforme de manejar rectángulos y cuadrados.
• Estructuras de datos heterogéneos. A veces es muy útil poder manipular conjuntos
similares de objetos. Con polimorfismo se pueden crear y manejar fácilmente estructuras
de datos heterogéneos, que son fáciles de diseñar y dibujar, sin perder la comprobación de
tipos de los elementos utilizados.
• Gestión de una jerarquía de clases. Las jerarquías de clases son colecciones de clases
altamente estructuradas, con relaciones de herencia que se pueden extender fácilmente.

Declaración de un tipo parametrizado Java

Al nombre de la colección le sigue el tipo de los elementos entre paréntesis angulares (< tipo>):
Coleccion<tipo> v;
Si se parametrizan dos tipos, como ocurre con los mapas, se separan con coma:
Coleccion<tipoClave,tipoValor> cc;

Por ejemplo:

Stack<Double> pila;
SortedMap<Integer,String> mapa;
Realmente con el tipo parametrizado es como si se hubiera declarado otra clase, en consecuencia
las instancias de colecciones parametrizadas se crean con esa clase, es decir new
Coleccion<tipo> crea la instancia. Por ejemplo:
pila = newStack<Double>();
mapa = newTreeMap<Integer,String>();



A continuación del nombre de la clase se especifican los tipos parametrizados entre
paréntesis angulares:
Coleccion<tipo1...> var;
Para crear instancias, new Coleccion<tipo1...>();
Por ejemplo:
Set<Integer> cn = new TreeSet<Integer>();


LinkedList JAVA

Esta clase organiza los elementos de una colección a la manera de una lista doblemente enlazada.
Las operaciones de inserción y borrado en posiciones intermedias son muy eficientes; por el
contrario, el acceso a un elemento por índice es ineficiente.
La clase dispone de un constructor sin argumentos que crea una lista vacía, y otro constructor
que crea la lista con los elementos de otra colección.
public LinkedList();
public LinkedList(Collection c);
Implementa la interfaz Cloneable; las operaciones generales de las listas y métodos específicos
que operan sobre el primer y último elemento son:
public Object getFirst()
public Object getLast()
public void addFirst(Object ob)
public void addLast(Object ob)
public Object removeFirst()
public Object removeFirst()
Se puede usar LinkedList para crear una estructura de datos Cola o Pila. Añadir datos a
la Cola se hace con addLast(), eliminar con removeFirst() y obtener el elemento frente con
getFirst().



ListIterator Java

Este iterador es específico de las colecciones que implementan la interfaz List. Permite recorrer
una lista en ambas direcciones, y también eliminar, cambiar y añadir elementos de la lista.
ListIterator deriva de Iterator, y su declaración es la siguiente:
public interface ListIterator extends Iterator
{
boolean hasNext();
Object next();
int nextIndex();
boolean hasPrevious();
Object previous();
int previousIndex();
void remove();
void set(object):
void add(Object);
}
Las colecciones con el comportamiento de Lista disponen de los métodos listIterator()
y listIterator(int i) que devuelve un objeto ListIterator, de tal forma que la primera
llamada a next() devuelve el primer elemento, o el de índice i respectivamente. Por ejemplo:
ListLinked ld = new ListLinked();
ListIterator iterBdir;
iterBdir = ld.listIerator(); // el elemento actual es el primero
iterBdir = ld.listIterator(4); // elemento actual es el 4

Hay que tener en cuenta que el primer elemento es el de índice 0, y que el previo a este tiene
el índice -1.
El significado de hasNext() y next() es el mismo que tienen en la interfaz Iterator. Los
métodos hasPrevious() y previous() permiten recorrer la lista en sentido inverso. hasPrevious()
devuelve true si hay un elemento anterior. previous() devuelve el elemento anterior,
levanta la excepción NoSuchElementException si no hay elemento previo.
remove() elimina el último elemento obtenido por next(), o bien por previous().
set(Object q) sustituye por q el último elemento obtenido por next(), o bien por previous().
add(Object q) inserta q inmediatamente antes del elemento que devolvería la llamada a
next() y después del elemento que devolvería la llamada a previous().

COLECCIONES EN JAVA

Las colecciones proporcionan programación genérica para muchas estructuras de datos. Una colección
es una agrupación de objetos relacionados que forma una única entidad; por ejemplo, un
array de objetos, un conjunto. El array, el vector, la matriz, en general, una Colección, es en sí
misma otro objeto que se debe crear. Por ejemplo:
class Pueblo { .... };
class Puerto { ... };
Pueblo [] col1 = new Pueblo[100];
Puerto [] col2 = new Puerto [100];
LinkedList <String> conCad = // Lista de cadenas (en Java 1.5)
new LinkedList <String>();
Las colecciones incluyen: clases contenedoras para almacenar objetos, iteradores para acceder
a los objetos en el interior de los contenedores y algoritmos para manipular los objetos
(métodos de clases).
Las clases Colección guardan objetos de cualquier tipo; de hecho, el elemento base es Object
y, por consiguiente, debido a la conversión automática, se podrá añadir a la colección un objeto de
cualquier tipo.
EJEMPLO:

Considerar una aplicación en la que se debe almacenar n objetos del tipo Punto2D, Punto3D
y PuntoPolar.
Se realiza un almacenamiento secuencial, para ello se declara una array de tipo Object.
De esa forma se puede asignar cualquier objeto. El problema surge al recuperar los elementos
del array, ya que se debe hacer un cast al tipo clase, que puede ser Punto2D, Punto3D y
PuntoPolar.
class Punto2D { ... }
class Punto3D { ... }
class PuntoPolar { ... }
La declaración y creación del array de N elementos es:
final int N = 99;
Object [] rr = new Object[N];
int i = 0;
Asignación secuencial de objetos:
mas = true;
while (mas && (i < N))
{
int opc;
opc = menu();
if (opc == 1)
rr[i++] = new Punto2D();
else if (opc == 2)
rr[i++] = new Punto3D();
if (opc == 3)
rr[i++] = new PuntoPolar();
else mas = false;
}
Asignar elementos en un array es una operación muy eficiente. Una de las limitaciones
de los arrays es el tamaño, dado que al ser su tamaño fijo si se llena hay que ampliarlo. Por
el contrario, una característica importante de las clases Colección es que se redimensionan
automáticamente y, en consecuencia, el programador se despreocupa de controlar el número de
elementos, y puede colocar tantos elementos como sea necesario.
Cuando se vaya a trabajar con tipos de datos simples, o cuando se conozca el tipo
de dato de los elementos y el tamaño final, resulta muy eficiente utilizar arrays. En
cualquier otro caso, será conveniente utilizar alguna de las colecciones proporcionadas
en java.util.


Algoritmo de Kruscal Java

Kruskal propone otra estrategia para encontrar el árbol de expansión de coste mínimo. El árbol
se empieza a construir con todos los vértices del grafo G pero sin aristas; se puede afirmar
que cada vértice es una componente conexa en sí misma. El algoritmo construye componentes
conexas cada vez mayores examinando las aristas del grafo en orden creciente del peso. Si la
arista conecta dos vértices que se encuentran en dos componentes conexas distintas, entonces se
añade la arista al árbol de expansión T. En el proceso, se descartan las aristas que conectan dos
vértices pertenecientes a la misma componente, ya que darían lugar a un ciclo si se añaden al
árbol de expansión ya que están en la misma componente. Cuando todos los vértices están en un
solo componente, T, éste es el árbol de expansión de coste mínimo del grafo G.
El algoritmo de Kruskal asegura que el árbol no tiene ciclos, ya que para añadir una arista, sus
vértices deben estar en dos componentes distintas; además es de coste mínimo, ya que examina
las aristas en orden creciente de sus pesos.
La Figura 16.7 muestra un grafo y, a continuación, se obtiene su árbol de expansión, aplicando
este algoritmo. En primer lugar se obtiene la lista de aristas en orden creciente de sus pesos:
{(1,3), (1,2), (2,4), (1,5), (2,3), (3,4), (5,6), (4,5), (1,6)}
La primera arista que se toma es (1,3), como muestra la Figura 16.10a; a continuación, las
aristas (1,2), (2,4) y (1,5), en las que se cumple que los vértices forman parte de dos componentes
conexas diferentes, como se observa en la Figura 16.10b. La siguiente arista, (2,3) como sus
vértices están en la misma componente, por tanto se descarta; la arista (3,4) por el mismo motivo
se descarta. Por último, la arista (5,6), que tiene sus vértices en dos componentes diferentes, pasa
a formar parte del árbol, y el algoritmo termina ya que se han alcanzado todos los vértices.


Algoritmo de Prim Java

package Grafo;
public class ArbolExpansionMinimo
{
private int [][] Pesos;
private int n; // vértice origen y número de vértices
public ArbolExpansionMinimo(GrafMatPeso gp) // constructor
{
n = gp.numeroDeVertices();
Pesos = gp.matPeso;
}
public int arbolExpansionPrim() // implementación del algoritmo
{
int longMin, menor;
int z;
int [] coste = new int [n];
int [] masCerca = new int [n];
boolean [] W = new boolean [n];
for (int i = 0; i < n; i++)
W[i] = false; // conjunto vacío
longMin = 0;
W[0] = true; //se parte del vértice 0
// inicialmente, coste[i] es la arista (0,i)


for (int i = 1; i < n; i++)
{
coste[i] = Pesos[0][i];
masCerca[i] = 0;
}
for (int i = 1; i < n; i++)
{ // busca vértice z de V-W mas cercano,
// de menor longitud de arista, a algún vértice de W
menor = coste[1];
z = 1;
for (int j = 2; j < n; j++)
if (coste[j] < menor)
{
menor = coste[j];
z = j;
}
longMin += menor;
// se escribe el arco incorporado al árbol de expansión
System.out.println("V" + masCerca[z] + " -> " + "V" + z);
W[z] = true; // vértice z se añade al conjunto W
coste[z] = GrafMatPeso.INFINITO;
// debido a la incorporación de z,
// se ajusta coste[] para el resto de vértices
for (int j = 1; j < n; j++)
if ((Pesos[z][j] < coste[j]) && !W[j])
{
coste[j] = Pesos[z][j];

masCerca[j] = z;
}
}
return longMin;
}
}

ALGORITMO DE FLOYD JAVA

En algunas aplicaciones resulta interesante determinar el camino mínimo entre todos los pares
de vértices de un grafo dirigido y valorado. Considerando como vértice origen cada uno de los
vértices del grafo, el algoritmo de Dijkstra resuelve el problema. Existe otra alternativa, más
elegante y más directa, propuesta por Floyd que recibe el nombre de algoritmo de Floyd.
El grafo, de nuevo, está representado por la matriz de pesos, de tal forma que todo arco
(vi,vj) tiene asociado un peso cij; si no existe arco, cij = ∞. Además, cada elemento de la
diagonal, cii, se hace igual a 0. El algoritmo de Floyd determina una nueva matriz, D, de n x n
elementos tal que cada elemento, Dij, contiene el coste del camino mínimo de vi a vj .
El algoritmo tiene una estructura similar al algoritmo de Warshall para encontrar la matriz de
caminos. Se generan consecutivamente las matrices D1, D2, ..., Dk, ... , Dn a partir de la matriz
Do que es la matriz de pesos. En cada paso se incorpora un nuevo vértice y se estudia si con ese
vértice se puede mejorar los caminos para ser más cortos. El significado de cada matriz es:
D0[i,j] = cij coste (peso) del arco del vértice i al vértice j
∞ si no hay arco.

D1[i,j] = minimo(D0[i,j],D0[i,1]+D0[1,j]).
Menor de los costes entre el anterior camino mínimo de i a j y la suma de costes
de caminos de i a 1 y de 1 a j.
D2[i,j] = minimo(D1[i,j],D1[i,2]+D1[2,j]).
Menor de los costes entre el anterior camino mínimo de i a j y la suma de los
costes de caminos de i a 2 y de 2 a j.
En cada paso se incorpora un nuevo vértice para determinar si hace el camino menor entre
un par de vértices.
Dk[i,j] = minimo(Dk-1[i,j],Dk-1[i,k]+Dk-1[k,j]).
Menor de los costes entre el anterior camino mínimo de i a j y la suma de los
costes de caminos de i a k y de k a j.
De forma recurrente, se añade en cada paso un nuevo vértice para determinar si se consigue
un nuevo camino mínimo, hasta llegar al último vértice y obtener la matriz Dn, que es la matriz
de caminos mínimos del grafo.

Se define la clase TodoCaminoMinimo para implentar el algoritmo al que se añade un pequeño
cambio: guardar, en la matriz traza, el índice del último vértice que ha hecho que el camino
sea mínimo desde el vértice vi al vj, para cada par de vértices del grafo.
package Grafo;
public class TodoCaminoMinimo
{
private int [][] pesos;
private int [][] traza;
private int [][] d;
private int n; // número de vértices
public TodoCaminoMinimo(GrafMatPeso gp)
{
n = gp.numeroDeVertices();
pesos = gp.matPeso;
d = new int [n][n];
traza = new int [n][n];
}
public void todosCaminosMinimo()
{
// matriz inicial es la de pesos.
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
d[i][j] = pesos[i][j];
traza[i][j] = -1; // indica que camino mas corto es el arco
}

// Camino mínimo de un vértice a si mismo: 0
for (int i = 0; i < n; i++)
d[i][i] = 0;
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if ((d[i][k] + d[k][j]) < d[i][j]) // nuevo mínimo
{
d[i][j] = d[i][k] + d[k][j];
traza[i][j]= k;
}
}
}

Algoritmo de Dijkstra Java

package Grafo;
public class CaminoMinimo
{
private int [][] Pesos;
private int [] ultimo;
private int [] D;
private boolean [] F;
private int s, n; // vértice origen y número de vértices
public CaminoMinimo(GrafMatPeso gp, int origen)
{
n = gp.numeroDeVertices();
s = origen;
Pesos = gp.matPeso;
ultimo = new int [n];
D = new int [n];
F = new boolean [n];
}
public void caminoMinimos()
{
// valores iniciales
for (int i = 0; i < n; i++)

{
F[i] = false;
D[i] = Pesos[s][i];
ultimo[i] = s;
}
F[s] = true; D[s] = 0;
// Pasos para marcar los n-1 vértices
for (int i = 1; i < n; i++)
{
int v = minimo(); /* selecciona vértice no marcado
de menor distancia */
F[v] = true;
// actualiza distancia de vértices no marcados
for (int w = 1; w < n; w++)
if (!F[w])
if ((D[v] + Pesos[v][w]) < D[w])
{
D[w] = D[v] + Pesos[v][w];
ultimo[w] = v;
}
}
}

{
int mx = GrafMatPeso.INFINITO;
int v = 1;
for (int j = 1; j < n; j++)
if (!F[j] && (D[j]<= mx))
{
mx = D[j];
v = j;
}
return v;
}
}
El tiempo de ejecución del algoritmo es cuadrático, se deduce que tiene una complejidad
cuadrática, O(n2 ), debido a los dos bucles anidados de orden n (número de vértices). Ahora
bien, en el caso de que el número de arcos, a, fuera mucho menor que n2, el tiempo de ejecución
mejora representando el grafo con listas de adyacencia. Entonces puede obtenerse un tiempo
O(alog n).

ALGORITMO DE WARSHALL JAVA

Se codifica el algoritmo para un grafo G representado por su matriz de adyacencia. El método
devuelve la matriz de caminos P.
public static int [][] matrizCaminos(GrafoMatriz g) throws Exception
{
int n = g.numeroDeVertices();
int [][] P = new int[n][n]; // matriz de caminos
// Se obtiene la matriz inicial: matriz de adyacencia
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
P[i][j] = g.adyacente(i,j) ? 1 : 0;
// se obtienen, virtualmente, a partir de P0, las sucesivas
// matrices P1, P2, P3 ,..., Pn-1, Pn que es la matriz de caminos
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
P[i][j] = Math.min(P[i][j] + P[i][k] * P[k][j], 1);
return P;
}

Implementación del algoritmo de ordenación topológica Java

La codificación del algoritmo depende de la representación del grafo, con matriz de adyacencia
o listas de adyacencia. Si el grafo tiene relativamente pocos arcos, (poco denso), la matriz de
adyacencia tiene muchos ceros (es una matriz esparcida), y entonces el grafo se representa con
listas de adyacencia. En el caso de grafos dirigidos densos se prefiere, por eficiencia, la matriz
de adyacencia. Con independencia de la representación, se utiliza una Cola para almacenar los
vértices con grado de entrada 0.
La siguiente codificación representa un grafo representado con listas de adyacencia (clase
GrafoAdcia); los vértices de la ordenación topológica se escriben por pantalla, y se guardan
en el vector T[].

import TipoCola.*;
import ListaGenerica.*;
// Método que devuelve el grado de entrada del vértice v .
// Se suponen los vértices numerados de 0 a n-1
public static int gradoEntrada(GrafoAdcia g, int v) throws Exception
{
int cuenta = 0;
for (int origen = 0; origen < g.numeroDeVertices(); origen++)
{
if (g.adyacente(origen, v)) // arco incidente a v
cuenta++;
}
return cuenta;
}
// Método para obtener una ordenación topológica.
// Muestra los vértices que pasan a formar parte de la
// ordenación, y se guardan en T[]
public static
void ordenTopologica(GrafoAdcia g, int[]T) throws Exception
{
int []arcosInciden;

int v, w, nvert;
ColaLista cola = new ColaLista();
nvert = g.numeroDeVertices();
arcosInciden = new int[nvert];
// grado de entrada de cada vértice
for (v = 0; v < nvert; v++)
arcosInciden[v] = gradoEntrada(g, v);
System.out.println("\n Ordenación topológica ");
for (v = 0; v < nvert; v++)
if (arcosInciden[v] == 0)
cola.insertar(new Integer(v));
VerticeAdy [] vs = new VerticeAdy[nvert];
vs = g.vertices();
while (!cola.colaVacia())
{
Integer a;
Arco elemento;
ListaIterador itl;
int j = 0;
a = (Integer)cola.quitar();
w = a.intValue();
System.out.print(" " + vs[w].toString());
T[j++] = w;

itl = new ListaIterador(g.listaAdyc(w)); // iterador de lista
// decrementa grado entrada de vértices adyacentes
while ((elemento = (Arco)itl.siguiente())!= null)
{
v = elemento.getDestino();
arcosInciden[v]--;
if (arcosInciden[v] == 0)
cola.insertar(new Integer(v));
}
}
}




Búsqueda secuencial Java

La búsqueda secuencial busca un elemento de una lista utilizando un valor destino llamado clave.
En una búsqueda secuencial (a veces llamada búsqueda lineal), los elementos de una lista o
vector se exploran (se examinan) en secuencia, uno después de otro. La búsqueda secuencial es
necesaria, por ejemplo, si se desea encontrar a la persona cuyo número de teléfono es 958-220000
en un directorio o listado telefónico de su ciudad. Los directorios de teléfonos están organizados
alfabéticamente por el nombre del abonado en lugar de por números de teléfono, de modo que deben
explorarse todos los números, uno después de otro, esperando encontrar el número 958-220000.
El algoritmo de búsqueda secuencial compara cada elemento del array con la clave de
búsqueda. Dado que el array no está en un orden prefijado, es probable que el elemento a buscar
pueda ser el primer elemento, el último elemento o cualquier otro. De promedio, al menos, el
programa tendrá que comparar la clave de búsqueda con la mitad de los elementos del array. El
método de búsqueda lineal funcionará bien con arrays pequeños o no ordenados.

ordenación Shell Java

public static void ordenacionShell(double a[])
{
int intervalo, i, j, k;
int n= a.length;
intervalo = n / 2;
while (intervalo > 0)
{
for (i = intervalo; i < n; i++)
{
j = i - intervalo;
while (j >= 0)
{
k = j + intervalo;
if (a[j] <= a[k])
j = -1; // par de elementos ordenado
else
{
intercambiar(a, j, j+1);
j -= intervalo;
}
}
}
intervalo = intervalo / 2;
}
}

algoritmo Quicksort Java


public static void quicksort(double a[])
{
quicksort(a, 0, a.length-1);
}
Y la codificación del método recursivo:
private static void quicksort(double a[], int primero, int ultimo)
{
int i, j, central;
double pivote;
central = (primero + ultimo)/2;
pivote = a[central];
i = primero;
j = ultimo;
do {
while (a[i] < pivote) i++;
while (a[j] > pivote) j--;
if (i <= j)
{
intercambiar(a, i, j);
i++;
j--;
}
}while (i <= j);
if (primero < j)
quicksort(a, primero, j); // mismo proceso con sublista izqda
if (i < ultimo)
quicksort(a, i, ultimo); // mismo proceso con sublista drcha
}

Algoritmo de ordenación Shell Java

public static void ordenacionShell(double a[])
{
int intervalo, i, j, k;
int n= a.length;
intervalo = n / 2;
while (intervalo > 0)
{
for (i = intervalo; i < n; i++)
{
j = i - intervalo;
while (j >= 0)
{
k = j + intervalo;
if (a[j] <= a[k])
j = -1; // par de elementos ordenado
else
{
intercambiar(a, j, j+1);
j -= intervalo;
}
}
}
intervalo = intervalo / 2;
}
}

lunes, 24 de junio de 2013

Obtención de cadenas de caracteres Java


Comparar cadenas Java


Usar equals(). Java


La longitud de una cadena Java


Ejemplo de concatenacion Java


Concatenacion de cadenas JAVA


Las cadenas de caracteres son objetos de tipo String JAVA


La clase String Java


lunes, 17 de junio de 2013

Dado N Números mostrar el mayor y el menor JAVA



package mayormenor;
import java.util.Scanner;

public class MayorMenor {


    public static void main(String[] args) {
     
        Scanner x=new Scanner(System.in);
     
        int n;
        int mayor,menor;
     
        System.out.println("Cantidad de números: ");
        n=x.nextInt();
     
        int[]numeros=new int[n];
     
        for(int i=0;i<n;i++)
        {
            System.out.println("Isnerta numero: ");
            numeros[i]=x.nextInt();
         
        }
        mayor=numeros[0];
        menor=numeros[0];
     
        for(int i=0;i<n;i++)
        {
            if(numeros[i]>mayor)
            {
                mayor=numeros[i];
             
            }
         
            if(numeros[i]<menor)
            {
                menor=numeros[i];
             
            }
         
        }
     
        System.out.println("El mayor es: "+mayor);
        System.out.println("El menor  es: "+menor);
     
             
   
    }
}

Dado N Números mostrar el mayor y el menor C#




using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NumeroMayorMenor
{
    class Program
    {
        static void Main(string[] args)
        {

            int n;
            int mayor;
            int menor;
            Console.WriteLine("Cantidad de números: ");
            n = Convert.ToInt32(Console.ReadLine());
            int[]numeros=new int[n];

            for (int i = 0; i < n; i++)
            {
                Console.WriteLine(" Inserta numero:");
                numeros[i] = Convert.ToInt32(Console.ReadLine());
            }

            mayor = numeros[0];
            menor = numeros[0];

            for (int i = 0; i < n; i++)
            {
                if (numeros[i] > mayor)
                {
                    mayor = numeros[i];
                }

                if (numeros[i] < menor)
                {
                    menor = numeros[i];
                }
            }


            Console.WriteLine("El mayor: "+mayor);
            Console.WriteLine("El menor: " + menor);
            Console.ReadLine();
        }
    }
}