Capitulos de este wiki
  1. 1 Búsquedas binarias

Búsquedas binarias - Búsquedas binarias

1 - Búsquedas binarias

Tutorial creado por joangarnet. Extraido de: http://www.joangarnet.com/blog/?p=264
20 de Septiembre de 2006

Me encontrado con la siguiente situación:
Un cliente me ha dado una base de datos ACCESS (.mdb) con 13 columnas y 16,796 registros para confeccionar un diccionario traductor.
Para poder trabajar con los datos desde Flash he tenido que hacer la conversión a .xml y el archivo resultante pesaba 6.5Mb y tenía 218,347 líneas. Unos tamaños algo indigestos para la mayoría de parseadores de XML...
La primera solución que se me planteó fue separar cada letra del abecedario en diferentes archivos xml, pero aún así seguía siendo demasiado para el parser del FlashPlayer.
Finalmente (viendo que ni MTASC me podía salvar) tuve que crearme un script php que:
- parseara el archivo xml
- separara por idiomas
- separara cada idioma por iniciales
- sacara todos los valores de cada inicial a un archivo .as en forma de array asociativo (array de objetos)
- luego con la librería Ming generar los archivos .swf que contendrán los arrays compilados listos para ser cargados dinámicamente

Una vez hecho esto he obtenido una estructura así:

+---ale
|       ale_a.swf
|       ale_b.swf
|       ale_c.swf
    ( ...... )
|       ale_w.swf
|       ale_x.swf
|       ale_y.swf
|       ale_z.swf
|
+---cast
|       cast_a.swf
|       cast_b.swf
    ( ...... )
|       cast_x.swf
|       cast_y.swf
|       cast_z.swf
|
+---fran
|       fran_a.swf
|       fran_b.swf
    ( ...... )
|       fran_x.swf
|       fran_y.swf
|       fran_z.swf
|
|---ing
        ing_a.swf
        ing_b.swf
        ing_c.swf
        ing_d.swf
        ing_e.swf
    ( ...... )

A partir de ahí es cuando ha entrado en juego el dilema de qué algoritmo de búsqueda utilizar para realizar las búsquedas totales y parciales de las palabras.
Por un lado he necesitado poder consultar el array a cada evento de teclado desde el campo de texto de búsqueda para conseguir la misma funcionalidad que al escribir algo en la barra de direcciones del navegador, que mientras escribes se te muestran las ocurrencias de palabras que contienen el segmento de cadena que has escrito.
Lo demás ha sido mucho más sencillo a partir de ahí...

Tras investigar por ahí varios sistemas de búsqueda he llegado a la conclusión que el más versátil son las búsquedas binarias (binary search), que te permiten realizar búsquedas muy rápidas sin consumir nada de memoria y poco de procesador.
El concepto de las búsquedas binarias es bastante sencillo, en la wikipedia viene una definición:

Búsqueda binaria
Para realizarla, es necesario contar con un array o arreglo ordenado. Luego tomamos el elemento que se encuentra a la mitad del arreglo (N/2) y lo comparamos con el elemento buscado. Si el elemento buscado es menor, ahora solo buscaremos del inicio hasta la mitad (N/2), en caso contrario, buscaremos de la mitad +1 (N/2+1) hasta el final.
El siguiente paso de la búsqueda se repite el procedimiento en la mitad del arreglo elegido donde se puede encontrar la solución y se repite, resultando en una búsqueda recursiva.
De esta forma la complejidad computacional se reduce a O(ln N)

He creado una implementación de la búsqueda binaria total y otra de búsqueda binaria parcial para poder comparar segmentos de cadena.
Las dos testeadas con arrays de miles de registros.

PLAIN TEXT
Actionscript:
  1. /**
  2. * @class   BinarySearchUtils
  3. * @author  Joan Garnet
  4. * @version 1.0
  5. * @license http://creativecommons.org/licenses/by-sa/1.0/
  6. * @date    Sun Dec 18 06:56:26 2005
  7. * @usage   var arr:Array = [5,2,8,7,65,12,10,9,6,4,6,7,8,2,1,3,6,9,12,54,65,78,7,5,4,6];
  8. *          arr.sort (Array.NUMERIC);
  9. *          trace (arr);
  10. *          var index:Number = com.joangarnet.utils.BinarySearchUtils ( arr, 6 );
  11. *          trace (index)
  12. *          trace (arr[index])
  13. *
  14. *          var arr:Array = ["apple","orange","apple","nectarine","lemon","apple"];
  15. *          arr.sort ();
  16. *          trace (arr);
  17. *          var index:Number = com.joangarnet.utils.BinarySearchUtils ( arr, "apple" );
  18. *          trace (index)
  19. *          trace (arr[index])
  20. */
  21. class com.joangarnet.utils.BinarySearchUtils
  22. {
  23.     /**
  24.      * Busca la coincidencia de [terminoBusqueda] en [arrayDeBusqueda] con índice menor
  25.      * binarySearch basado en la implementación en Java de Tim Bray ( http://www.tbray.org/ongoing/When/200x/2003/03/22/Binary )
  26.      *
  27.      * @param   arrayDeBusqueda: (Array) de Strings o Numbers ordenado
  28.      * @param   terminoBusqueda: (Number) o un String
  29.      * @param   key:             (String). Corresponde a la clave en la que buscar si se trata de un array asociativo
  30.      * @return  Devuelve -1 si no se ha encontado la coincidencia o, si se ha encontrado, la posición
  31.      *          en el Array donde se encuentra (la de índice menor en el caso que esté repetida)
  32.      */
  33.     static public function binarySearch ( arrayDeBusqueda:Array, terminoBusqueda:Object, key:String ):Number
  34.     {
  35.         var alto:Number = arrayDeBusqueda.length;
  36.         var medio:Number;
  37.         var bajo:Number = -1;
  38.         while ((alto - bajo)> 1)
  39.         {
  40.             medio = Math.floor ((alto + bajo) / 2);
  41.         if (key==undefined) var arrValue=arrayDeBusqueda[medio]; else var arrValue = arrayDeBusqueda[medio][key];
  42.             if (arrValue <terminoBusqueda)
  43.             {
  44.                 bajo = medio;
  45.             }
  46.             else
  47.             {
  48.                 alto = medio;
  49.             }
  50.         }
  51.         if (key==undefined) var arrValue=arrayDeBusqueda[alto]; else var arrValue = arrayDeBusqueda[alto][key];
  52.         if (alto == arrayDeBusqueda.length or arrValue != terminoBusqueda)
  53.         {
  54.             return -1;
  55.         }
  56.         else
  57.         {
  58.             return alto;
  59.         }
  60.     }
  61.  
  62.     /**
  63.      * Busca la coincidencia parcial de [terminoBusqueda] en [arrayDeBusqueda.substr(0,terminoBusqueda.length)] con índice menor
  64.      *
  65.      * @param   arrayDeBusqueda: (Array) de Strings ordenado
  66.      * @param   terminoBusqueda: (String)
  67.      * @param   key:             (String). Corresponde a la clave en la que buscar si se trata de un array asociativo
  68.      * @return  Devuelve -1 si no se ha encontado la coincidencia o, si se ha encontrado, la posición
  69.      *          en el Array donde se encuentra (la de índice menor en el caso que esté repetida)
  70.      */
  71.     static public function binarySubstringSearch ( arrayDeBusqueda:Array, terminoBusqueda:String, key:String ):Number
  72.     {
  73.         var strLen:Number = terminoBusqueda.length;
  74.         var alto:Number = arrayDeBusqueda.length;
  75.         var medio:Number;
  76.         var bajo:Number = -1;
  77.         while ((alto - bajo)> 1)
  78.         {
  79.             medio = Math.floor ((alto + bajo) / 2);
  80.         if (key==undefined) var arrValue=arrayDeBusqueda[medio]; else var arrValue = arrayDeBusqueda[medio][key];
  81.             var substrDeBusqueda:String = arrValue.substr (0, strLen);
  82.             if (substrDeBusqueda <terminoBusqueda)
  83.             {
  84.                 bajo = medio;
  85.             }
  86.             else
  87.             {
  88.                 alto = medio;
  89.             }
  90.         }
  91.     if (key==undefined) var arrValue=arrayDeBusqueda[alto]; else var arrValue = arrayDeBusqueda[alto][key];
  92.         var substrDeBusqueda:String = arrValue.substr (0, strLen);
  93.         if (alto == arrayDeBusqueda.length or substrDeBusqueda != terminoBusqueda)
  94.         {
  95.             return -1;
  96.         }
  97.         else
  98.         {
  99.             return alto;
  100.         }
  101.     }
  102. }

BinarySearchUtils class
zip

Enlaces relacionados:
* On the Goodness of Binary Search
* Búsqueda binaria

Sé el primero en opinar


Tutoriales relacionados con 'Búsquedas binarias'

Me encontrado con la siguiente situación: Un cliente me ha dado una base de datos... Más »

Autor y licencia de 'Búsquedas binarias'


Tutorial de joangarnet. Extraido de: http://www.joangarnet.com/blog/?p=264 CopyLeft
Este contenido ha sido recopilado por el equipo de Wikilearning. Todo el contenido recopilado se ha obtenido respetando y comunicando en nuestro site la licencia de cada fuente.
Wikilearning tiene permiso expreso por escrito de los autores para publicar los contenidos que ha extraído de otras webs, incluyendo su uso comercial.