jueves, 24 de febrero de 2011

Puntos clave del tema 1

Al ir finalizando cada tema de la asignatura de Programación II, enumeraré los puntos principales del mismo,  ya estén relacionados con el lenguaje de programación Java o con cualquier otra materia relacionada con la asignatura, y proporcionaré alguna referencia adicional para todo aquel que quiera profundizar en ellos.

Estos son los puntos clave del tema 1:
 ¿Hay alguno de estos puntos que os de más problemas que otros?

¿Os gustaría que incidiéramos más en alguno de ellos?

viernes, 18 de febrero de 2011

¿Qué tipo de datos elijo?

Java proporciona un conjunto predefinido de tipos de datos para definir variables; elegir un tipo de datos u otro dependerá de distintas cosas tales como qué queremos almacenar en la variable (un número, una letra, etc.), qué valores máximos o mínimos necesito almacenar (en el caso de números) o cualquier otra necesidad específica (ej., que la variable ocupe poco en memoria).

Otro elemento a tener en cuenta, no a la hora de elegir un tipo de datos sino de usarlo, es el valor por defecto que toman las variables de los tipos de datos predefinidos cuando no son explícitamente inicializados en el código.

La siguiente tabla muestra los tipos de datos predefinidos de Java junto a su tamaño, su rango de valores y su valor por defecto.

Tipo de datosTamaño RangoValor por defecto
byte 8 bit [128 — 127]0
short 16 bit[-32.768 — 32.767]0
int 32 bit[-2.147.483.648 — 2.147.483.647]0
long 64 bit[-9.223.372.036.854.775.808 — 9.223.372.036.854.775.807]0L
float 32 bit[NaN, -∞, -(2-2-23)·2127 — -2-149, -0, +0, 2-149 — (2-2-23)·2127, +∞]0.0f
double 64 bit[NaN, -∞, -(2-2-52)·21023 — -2-1074, -0, +0, 2-1074 — (2-2-52)·21023, +∞]0.0d
boolean 1 bit 0, 1false
char 16 bit['\u0000' — '\uffff']'\u0000'

Fuente: Java Tutorials

viernes, 11 de febrero de 2011

Complejidad del algoritmo de búsqueda binaria

Para buscar un elemento dentro de un vector (array) hay que recorrer dicho vector, elemento a elemento, hasta encontrar el elemento en cuestión o hasta que se acabe el vector.

La complejidad de los algoritmos se calcula teniendo en cuenta el peor caso posible. Para el caso de una búsqueda en un vector de tamaño n, el peor caso es que el elemento no se encuentre en el vector, con lo que habría que recorrer los n elementos del vector antes de poder decir que el elemento no se encuentra en el mismo. A la complejidad de esta operación se la denomina de orden lineal (O(n)).

El algoritmo de búsqueda binaria (o búsqueda dicotómica) es un algoritmo de búsqueda en vectores ordenados que permite disminuir la complejidad de la búsqueda en dichos vectores.

La intuición detrás de la búsqueda binaria es la misma que cuando se busca en un diccionario; cuando se va a buscar una palabra que empieza por la letra "s", nadie comienza a leerse las palabras que empiezan por la "a", luego la "b", y así en adelante. Normalmente, se abre el diccionario por la mitad y, dependiendo de si la letra inicial por la que hemos abierto es mayor o menor que la que buscamos, descartamos la mitad de las palabras de la enciclopedia y ya solo buscamos en la mitad restante.

El pseudocódigo del algoritmo de búsqueda binaria se puede encontrar, por ejemplo, aquí. El algoritmo consiste en mantener unos índices que marcan los límites superior e inferior de la parte del vector que nos queda por analizar.

Para calcular la complejidad de este algoritmo, inicialmente en número de elementos por analizar es n. Tras la primera división, el número será como mucho n/2 (pues nos hemos quedado con la mitad de elementos); tras la segunda división, el número será como mucho n/4; y así sucesivamente. Por lo general, tras la división número i, el número de elementos por analizar será como mucho:
\[\frac{n}{2^i}\]

El peor caso se da cuando el elemento a buscar no se encuentra en el vector (es decir, cuando tras dividir los elementos por analizar nos quedemos con un número menor a 1). Por lo tanto, el número máximo de llamadas a realizar es el menor número m tal que:
\[\frac{n}{2^m} < 1\]


Transformando esta fórmula a un logaritmo en base 2, tenemos que:
\[n < 2^m\]

y que
\[\log n < m\]

es decir, que el número m depende, no del tamaño n del vector, sino del logaritmo de dicho n.

Es por esto que el algoritmo de búsqueda binaria tiene una complejidad de orden logarítmico (O(log n)).

Referencia:

Michael T. Goodrich y Roberto Tamassia. Data Structures and Algorithms in Java, Fifth edition. John Wiley & Sons. 2011.

¡Bienvenidos!

Al acabar la clase de hoy unos alumnos se me han acercado y me han hecho una pregunta que, por un lado, se salía un poco del temario de la lección y, por otro, requería una explicación un poco más larga que un simple (y posiblemente indescifrable) "O(log n)".

Por ello me he animado a iniciar este blog para incluir cosas fuera de temario, cosas curiosas, resoluciones de dudas o simplemente anécdotas sobre el mundo de la programación.

Espero que el blog facilite la comunicación con los alumnos de mi grupo y que les sea útil a ellos, al resto de grupos de la asignatura y a cualquiera interesado en el mundo de la programación.

No espero escribir muy frecuentemente en el blog, dependerá de los tópicos que vayan surgiendo. No obstante, estoy abierto a peticiones de la audiencia. :)