Go y Golang

Golang: algoritmo de búsqueda binaria

Introducción

Ya fue el turno de PHP, JavaScript, Java (con strings y números) y Python.

Hoy es el turno de uno de mis lenguajes de programación favoritos: Go. Veremos cómo se puede implementar la búsqueda binaria en los arreglos del lenguaje, tanto en cadenas como en números.

Al igual que en los otros ejercicios, veremos:

  • Búsqueda binaria recursiva en arreglos de números
  • Búsqueda binaria secuencial en arreglos de números
  • Implementación de búsqueda binaria recursiva en arreglos de strings o cadenas
  • Algoritmo de búsqueda binaria secuencial en arreglos de cadenas
Búsqueda binaria recursiva Golang

Ver en línea

He puesto este código en el playground de Go.

Explicación del algoritmo

Bueno, esto ya lo he dicho en los otros posts y te invito a leerlos, pero igualmente trataré de dar la explicación…

Antes de todo, el arreglo debe estar ordenado. Es un requisito; aquí no veremos cómo ordenarlo porque ese no es el tema; veremos cómo hacer la búsqueda binaria. Ten en mente eso porque es importante saberlo para entender el algoritmo.

Este algoritmo utiliza el enfoque de divide y vencerás. Va partiendo el arreglo en 2 cada vez. Por ejemplo, la primera vez tal vez mida 6, luego medirá 3, luego 1 y así. El algoritmo es sencillo:

Calcula el elemento del medio sumando izquierda y derecha, dividiendo entre 2 ese resultado y luego redondeando hacia abajo. Si, por ejemplo, tenemos un arreglo de 5, la primera vez izquierda es 0 y derecha es 4, la mitad es redondearHaciaAbajo((0 + 4) / 2) que es igual a 2. Si fuera de 6, sería redondearHaciaAbajo((0 + 5) / 2) que daría algo como redondearHaciaAbajo(2.5), lo que resultaría en 2 de nuevo.

Una vez que ya sabemos en dónde está la mitad, obtenemos el valor que se encuentra en esa posición del arreglo. Lo comparamos con la búsqueda y en caso de que sea ese, regresamos el índice y el algoritmo termina.

Pero en caso de que el elemento de la mitad no coincida, se compara lo que buscamos. Debido a que el arreglo está ordenado, si el elemento del medio es mayor a la búsqueda, puede que lo que busquemos esté hacia la izquierda de esa mitad, y si el elemento de la mitad es menor a la búsqueda, tal vez lo que busquemos esté a la derecha.

Hacemos un if, y partimos el arreglo, ya sea desde izquierda hasta la mitad menos uno, o desde la mitad más uno hasta derecha.

En determinado momento encontraremos el elemento a la mitad del arreglo, y si no, entonces izquierda será más grande que derecha; justo ahí indicamos que no se encontró lo que buscamos y devolvemos -1.

Cómo comparar las cadenas

Afortunadamente (y no me esperaba menos de un lenguaje tan bonito) en Go podemos comparar cadenas como comparamos números. Es decir, usamos los operadores >, < y todos esos. Este lenguaje trata a las cadenas lexicográficamente, así que no necesitamos usar algo como compareTo como lo hicimos con Java.

Cabe mencionar que la función Compare sí existe en go, pero incluso ellos recomiendan que no la usemos; que siempre es más rápido y limpio usar los operadores binarios.

Cosas que importar

En las funciones no se ve, pero necesitamos importar la librería (o como se le diga) math. En la implementación usamos funciones de fmt, así que igualmente puedes importarlo.

See the gist on github.

Búsqueda binaria recursiva y secuencial en Go

Vamos a ver todas las implementaciones, que en total son 4. Al final veremos cómo podemos usarlas. El algoritmo es el mismo, sólo que algunas usan while y otras recursividad. Recuerda que la condición de salida es igual para todas: que izquierda sea mayor que derecha.

Con arreglos numéricos y recursividad

Comencemos viendo lo más fácil, una búsqueda binaria en un arreglo que tiene números enteros. Aquí el código:

See the gist on github.

Así de sencillo es. Disculpen por todos los casteos que se hacen, pero son necesarios para que el compilador no se queje. Por ejemplo, la función math.Floor recibe un float64, no un int, pero como no somos matemáticos y no nos importa si perdemos precisión, lo casteamos.

Más tarde, convertimos lo que devuelva math.Floor a int, porque devuelve un float64. Esto, si bien se ve sucio, sirve bastante bien porque es mejor que el lenguaje no nos deje perder precisión sin que nosotros lo indiquemos explícitamente cuando estamos trabajando con números grandes o flotantes.

Y si no sabes qué es math.Floor yo te cuento: sirve para redondear números hacia abajo.

Usando arreglos numéricos y while

Lo mismo de arriba pero en un ciclo while. Aunque en Go no existe while, sí existe el ciclo while. Es decir; no existe la palabra reservada, pero podemos hacer el ciclo usando for. Recuerda: For is Go’s “while”

See the gist on github.

El algoritmo es el mismo, ya lo dije. Lo que cambia es que la función ahora recibe únicamente el arreglo y la búsqueda, porque la izquierda y la derecha son calculadas internamente y movidas dentro del ciclo while.

Con arreglos de cadenas y de forma recursiva

Ahora veamos el enfoque de comparar cadenas usando recursión. Es igual al numérico, sólo cambian los tipos de datos que recibimos.

See the gist on github.

No te confundas, el índice del elemento sigue siendo un entero, pero el elemento en sí es un string. Igualmente comparamos a las cadenas con los operadores binarios, así como en los números.

Ciclo while para implementar búsqueda binaria en arreglos de cadenas

El último algoritmo que nos trae aquí es la búsqueda binaria pero de forma secuencial; sobre arreglos de cadenas. Es como el de números, únicamente cambian los tipos de datos.

See the gist on github.

Con eso terminamos los 4 algoritmos que son muy parecidos entre sí. Veamos cómo se implementan.

Probar todas las funciones

He declarado unos arreglos y variables en la función main. Toda la función se ve así:

See the gist on github.

Lo que hace es usar los 4 algoritmos e imprimir los resultados en la consola. Ahora que leo esto, puede que el código sea más rápido si pasamos el arreglo por referencia, sería de probar.

Pero bueno, al ejecutarlo se ve así:

Búsqueda binaria en Go

Con eso terminamos.

Encantado de ayudarte


Estoy disponible para trabajar en tu proyecto, modificar el programa del post o realizar tu tarea pendiente, no dudes en ponerte en contacto conmigo.

No te pierdas ninguno de mis posts

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

Entradas recientes

Enviar mensaje con bot de Telegram usando JavaScript (lado del cliente)

Hoy te enseñaré cómo enviar un mensaje a un usuario desde un bot de Telegram…

6 horas hace

PHP: incrustar imagen en base64

El día de hoy te enseñaré algo muy sencillo pero útil al programar con PHP:…

7 horas hace

Plugin ESC POS – Actualización 3.4.0: imprimir HTML

El plugin para imprimir en impresoras térmicas alcanza hoy su versión 3.4.0 agregando soporte para…

1 día hace

JavaScript (lado del cliente): leer pixeles de imagen

En ocasiones es necesario leer los pixeles y colores de una imagen con JavaScript del…

1 semana hace

PHP y JavaScript: llenar select con AJAX

Siguiendo con los tutoriales de listas desplegables o select con JavaScript, vamos a ver cómo…

1 semana hace

Imprimir PDF generado con HTML

Hoy vamos a ver programar la impresión de un PDF generado a partir de HTML…

1 semana hace

Esta web usa cookies.