Sep 25 2008

Convertir un entero base 10 a binario en Java (Recursivo) {

Tag: Algoritmos, Java

En este ejemplo tenemos una aplicación simple que pide un número y lo convierte a binario utilizando un algoritmo recursivo con una variable externa.

Lo primero que tenemos que saber es cómo convertir un número de base 10 a binario, (base 2). Para ello, se divide el número deseado entre 2 y cada resultado de la división tantas veces como sea necesario hasta obtener el número indivisible, el 1. Luego se toman el último resultado, 1 y todos los restos de las divisiones, viendo la imagen va a quedar mucho más claro el concepto.
Divisiones necesarias para convertir un número a binario

A continuación veremos el código en Java necesario para pedir el número en base 10 y devolverlo en binario, por supuesto que se pueden agregar validaciones, de hecho hay que agregar validaciones para asegurarnos que el usuario ingrese un número, pero ese no es el objetivo de este post.

import java.io.BufferedReader;
import java.io.InputStreamReader;
 
class binario
{
	public static void main(String[] args)
	{
		InputStreamReader isr = new InputStreamReader(System.in);
		BufferedReader rdr = new BufferedReader(isr);
		System.out.print("Ingrese un número entero: ");
		String buffer = "0";
		try
		{
			buffer = rdr.readLine();
		}
		catch(java.io.IOException e) // Es obligatorio manejar la IOException, si se omite no compila
		{
			System.out.println(e);
		}
 
		int dec = Integer.parseInt(buffer);
		System.out.print("El valor binario correspondiente es: ");
 
		if(dec == 0)
			System.out.println(dec); // Cero en cualquier base es cero
		else
			System.out.println(obtenerBinario(dec)); // llamamos a la func. recursiva
	}
 
 
	static String aux = ""; // variable auxiliar utilizada para almacenar el resto de cada división
 
	static String obtenerBinario(int decimal)
	{
		if(decimal == 1) // Límite de la recursividad
			return Integer.toString(decimal) + aux; // Devolvemos 1 y los restos anteriores
		else
		{
			aux = aux + Integer.toString(decimal % 2); //guardamos el resto en la variable auxiliar
			return obtenerBinario(decimal / 2); // hacemos el llamado recursivo con el resultado de la división
		}
	}
}

Además del algoritmo para convertir los números, vale la pena ver la forma en que se lee la entrada estándar, utilizando un BufferedReader, pero eso lo veremos con mayor profundidad en otro post.

}


Sep 18 2008

Patrón Estrategia: Definición y ejemplo en Java {

El patrón Estrategia (Strategy) define una familia de algoritmos, los encapsula y hace intercambiables. Permitiendo a cada algoritmo variar independientemente de los clientes que lo utilizan.

Se utiliza para encapsular aquellas partes del código que varían, haciendo que éstas variaciones no afecten al resto del código, evitando así consecuencias inesperadas y brindando a nuestro código una mayor flexibilidad.

Para ilustrarnos con un ejemplo, supongamos que tenemos un grupo de terminales las cuales tienen su propio método de entrada y salida de datos, por ej. teclado, monitor, mouse, etc.
Supongamos que en éste momento sólo tenemos 3 métodos de entrada y 2 de salida, pero sabemos que en el futuro se van a agregar más, por ello recurriremos al Patrón Estrategia para encapsular los métodos de entrada y salida, permitiéndonos en el futuro implementar las nuevas terminales con gran facilidad y sin afectar a las ya existentes.

Para encapsular los métodos de entrada recurriremos al uso de interfaces, crearemos una interface Entrada y una Salida, las cuales serán implementadas por cada método de entrada/salida de datos. A su vez, necesitamos tener varias terminales y poder agregar los nuevos tipos, para ello utilizaremos herencia, todas nuestras terminales heredarán de la superclase Terminal.

La clase Terminal tendrá una variable de instancia del tipo Entrada (interface) y una del tipo Salida (interface).
Además crearemos una clase por cáda método de entrada y salida las cuales implementarán la interface correspondiente. También podremos definir una clase, por ejemplo Monitor_TouchScreen que implemente ambas interfaces, por lo que podremos utilizarlo como método de entrada y salida.

En los diagramas vemos las interfaces Entrada y Salida con las clases que la implementan, y la superclase Terminal con sus subclases.

Ahora podemos ir un paso más allá y crear una Terminal Mutable, (qué nombre, no?), por ese nombre me refiero a una Terminal que pueda cambiar sus método de entrada y/o salida en tiempo de ejecución, lo cual suena mucho más complejo de lo que realmente es, ya que la única diferencia con las terminales que hemos creado hasta el momento es que en esta tendremos que definirnos un setter para el método de entrada y uno para el método de salida, mientras que el resto no varía.

Luego de descargar esta implementación en Java hay que ir al directorio bin/ y ejecutar java TestTerminales

Ejemplo de Patrón Estrategia en Java (7.72 KB)

}


Sep 16 2008

Corte de Control - Algoritmo y Ejemplo en C# {

Tag: Algoritmos, C#

Un Corte de Control es un algoritmo muy usado a la hora de listar datos. Actualmente es más factible obtener los datos con una consulta SQL, pero el Corte de Control aún es una técnica válida.

Un Corte de Control se compone de 3 partes básicas: principio, cuerpo y fin, en pseudo código sería así:

while(i < cantidadElementos)
{
     principio; // inicializar variables y condiciones, obtener datos, etc.
 
     cuerpo; // recorrer los datos respetando la condición.
 
     fin; // mostrar los datos.
}

En nuestro ejemplo tendremos datos de alumnos y cursos, la estructura es como si fuese una base de datos, entonces nuestras tablas tendrían la siguiente estructura:

Alumnos Cursos
ID int ID int
IDCurso int Descripción string
Nombre string

Y nosotros necesitamos hacer un Corte de Control por ID de Cursos (criterio del corte) para listar los alumnos agrupados por curso, entonces el algoritmo se vería de la siguiente manera:

static void corteDeControl()
        {
            // -- principio del corte
            int i= 0; // variable utilizada para iterar en la lista de cursos
            int IDCursoAnterior = 0; // variable con la condición del corte
            Dictionary<int, List<alumno>> resultado = new Dictionary<int, List<alumno>>(); // resultado del corte
            Console.WriteLine("\n\nListado de alumnos por curso\n"); // imprimir encabezado
 
            // -- cuerpo del corte
            while (i < DS.Cursos.Count)
            {
                IDCursoAnterior = DS.Cursos[i].ID; // condición del corte
 
                while (i < DS.Cursos.Count && DS.Cursos[i].ID == IDCursoAnterior) // mientras se cumpla la condición del corte
                {
                    foreach (alumno a in DS.Alumnos) // buscar los alumnos que pertenezcan a ese curso
                    {
                        if (a.IDCurso == IDCursoAnterior)
                        {
                            if (resultado.ContainsKey(IDCursoAnterior))
                            {
                                resultado[IDCursoAnterior].Add(a);
                            }
                            else
                            {
                                List<alumno> lista = new List<alumno>();
                                lista.Add(a);
                                resultado.Add(IDCursoAnterior, lista);
                            }
                        }
                    }
                i++; // siguiente iteración
                }
            }
 
            //fin del corte
            imprimir(resultado); // mostrar el listado
        }

Resumiendo, en pseudo código, el cuerpo del corte de control se vería más o menos así:

while(i < cantidadElementos)
{
     IDAnterior = items[i]; // condición del corte
     while(i < cantidadElementos && IDActual = IDAnterior)
     {
          // proceso datos
     }
     i++;
}

Puedes descargar una solución de Visual Studio 2005 con el ejemplo (25.93 KB).

}


Sep 10 2008

Aprendamos a usar Expresiones Regulares (parte 1) {

Tag: RegEx

Una expresión regular es un conjunto de caracteres y símbolos que definen una cadena según un patrón y no por sus elementos; por ejemplo, si queremos representar una cadena de caracteres que sólo puede estar formada por las letras a, b, c y los números del 1 al 3, utilizaremos el siguiente patrón: ^([a,b,c,1,2,3]+)$.

Ahora veamos los signos básicos en las expresiones regulares y su significado:

^ Inicio de la cadena
$ Fin de la cadena
[] Cualquier caracter del conjunto, por ejemplo [xyz] representa el conjunto formado por las letras x,y,z y encontrará cualquiera de esos caracteres.
[^] Cualquier caracter no incluido en el conjunto, por ejemplo[^xyz] representa cualquier caracter no incluido en el conjunto formado por las letras x,y,z
? Cero o una ocurrencia de lo que precede al símbolo, por ejemplo para encontrar cero o una ocurrencia de www. utilizaremos el patrón (www\.)?
+ El caracter que le precede debe aparecer al menos una vez, por ejemplo Google, Gooogle, Gooooooogle se representa con la siguiente expresión regular: Goo+gle
* El caracter que le precede debe aparecer cero, una o más veces, utilizando el ejemplo anterior, Gooo*gle representa Google, Goooogle, Goooooogle.
{x} x ocurrencias del caracter que lo precede, por ejemplo www. podría ser representado con el patrón w{3}\.
{x,z} Entre x y z ocurrencias del caracter que lo precede, con el ejemplo de Google, si quisiéramos que hubieran mínimo 2 letras o y máximo 5, utilizaríamos el patrón Go{2,5}gle
{x,} x o más ocurrencias de lo que lo precede, con el ejemplo de Google, para tener 2 o más letras o usaríamos la expresión regular Go{2,}gle

Esos son los signos básicos de las expresiones regulares, también tenemos la barra invertida, que se utiliza como caracter de escape en ciertos casos, cuando se desea incuir un caracter especial como ., * o ?, y para definir tipos de caracteres en otros, vemos algunos casos.

\. Un punto dentro del patrón, como definimos en uno de los ejemplos anteriores, la expresión w{3}\. define la cadena www.
\s Representa un espacio en blanco
\d Un dígito numérico
\w Un caracter alfanumérico
\n Un salto de línea
\r Representa el caracter de retorno de carro
\t Tabulador
\S Cualquier caracter excepto un espacio en blanco
\D Cualquier caracter excepto un dígito numérico
\W Representa cualquier caracter no alfanumérico

Esta es una introducción muy básica al uso de expresiones regulares, simplemente hemos visto algunos de los signos más básicos, en la próxima parte de este artículos veremos como crear algunas expresiones un poco más complejas. Mientras tanto pueden ir probando algunas expresiones en regexpal.com, un intérprete online de expresiones regulares.

}


Página 1 de 11