Foros del Web » Programando para Internet » PHP »

[Aporte copado] Busqueda similar con Levenshtein

Estas en el tema de [Aporte copado] Busqueda similar con Levenshtein en el foro de PHP en Foros del Web. si bien saque esta info de php-hispano, puede resultar util a las FAQs del foro La finalidad de este buscador no es otra que la ...
  #1 (permalink)  
Antiguo 13/04/2010, 10:48
Avatar de aldo1982  
Fecha de Ingreso: noviembre-2004
Ubicación: Santa Fe (Argentina) Colon F.C
Mensajes: 1.362
Antigüedad: 19 años, 5 meses
Puntos: 6
De acuerdo [Aporte copado] Busqueda similar con Levenshtein

si bien saque esta info de php-hispano, puede resultar util a las FAQs del foro

La finalidad de este buscador no es otra que la de poder hacer busquedas similares mucho mas potentes que el típico 'like' de MySQL. La función principal que uso es una función que me devuelve la distancia Levenshtein entre dos palabras y con unos algoritmos de ordenacion guardo las mas parecidas.

Una clara aplicación práctica de este metodo es el que se usa en la pagina oficial de PHP en la busqueda de funciones. Al buscar levenshtei (que en realidad se escribe levenshtein) nos salen las funciones parecidas, y la mas parecida remarcada en negrita.

Código PHP:
<?php
/*
* Módulo para búsqueda avanzada con levenshtein()
* - http://es2.php.net/manual/es/function.levenshtein.php)
*
* Creado por Voronwë - voronwe[arroba]elponeypisador.com
* Ejemplo:
* Palabra buscada: palabra
* ¿Quisiste decir alguna de estas palabras?
*
* numero  palabra  letras diferentes
* |  1   palábra     1
* |  2   pabra       2
* |  3   palabraxx   2
*/

$db=mysql_connect('servidor','usuario','password') or die('Fallo en la conexión a la Base de datos.');
mysql_select_db('base_de_datos',$db) or die('Fallo en la conexión a la Base de datos.');
// Consulta para tener la lista de palabras en $palabras
$query "Select entrada From enciclopedia";
$result mysql_query($query$db);
$palabras = array();
while(
$palabra mysql_fetch_row($result)) {
   
$palabras[] = $palabra;
}
mysql_free_result($result);
// Palabra a buscar
$palabra_buscada $_GET['palabra'];
// Distancia mínima de palabras para que se consideran parecidas
$distancia_minima = -1;
// Distancia mínima de les palabras a mostar
$dm_lista 2// Recomendado 2 (con 3 es menos preciso, y con 4 falla)

// Función de ordenado que encontré en: http://es2.php.net/manual/en/function.usort.php#40652
// $desordenado[0]['campo1'] y $desordenado[1]['campo2'] existen
// Funcionamiento: $ordenado = array_alternate_multisort($desordenado, "campo1", SORT_DESC, "campo2", SORT_ASC);
function array_alternate_multisort() {
   
$arguments func_get_args();
   
$arrays    $arguments[0];
   for (
$c = (count($arguments)-1); $c 0$c--) {
       if (
in_array($arguments[$c], array(SORT_ASC SORT_DESC))) {
           continue;
       }
       
$compare create_function('$a,$b','return strcasecmp($a["'.$arguments[$c].'"], $b["'.$arguments[$c].'"]);');
       
usort($arrays$compare);
       if (
$arguments[$c+1] == SORT_DESC) {
           
$arrays array_reverse($arrays);
       }
   }
   return 
$arrays ;
}
// Fin de función

$palabras_encontradas 0;
foreach (
$palabras as $palabra) {
   
$palabra strtolower($palabra[0]);
   
// Calcula la distancia entre la palabra introducida y una
   //  de las que hay en la base de datos
   
$distancia_levenshtein levenshtein(strtolower($palabra_buscada), $palabra);

   
// Comprueba si la palabra es correcta
   
if ($distancia_levenshtein == 0) {
       
// Ha encontrado la palabra exacta
       
$encontrada $palabra;
       
$distancia_minima 0;
       
// Como ha encontrado la palabra exacta salimos del bucle
       
break;
   }

   
// Encontrar nada mas la palabra que mas se acerque
   /* if ($distancia_levenshtein <= $distancia_minima || $distancia_minima < 0) {
       $encontrada  = $palabra;
       $distancia_minima = $distancia_levenshtein;
   }*/

   // Creamos la lista de palabras parecidas (palabras a una distancia
   //  menor a la distancia levenshtein de la palabra)
   
if ($distancia_levenshtein <= $dm_lista) {
      
$lista[$palabras_encontradas]['pal'] = $palabra;
      
$lista[$palabras_encontradas]['lev'] = $distancia_levenshtein;
      
$palabras_encontradas++;
   }
}
// Imprimir la palabra encontrada
echo "<pre>Palabra buscada: $palabra_buscada\n";
// Si se ha encontrado la palabra exacta la imprimimos
if ($distancia_minima == && isset($encontrada)) {
   echo 
"La palabra exacta es: $encontrada\n";
} else {
// Si no, puede haber una lista de palabras o ninguna coincidencia
   
if (is_array($lista)) {
   
// Imprimir lista
      
echo "¿Quisiste decir alguna de estas palabras?<br >";
      
$lista_ordenada array_alternate_multisort($lista"lev"SORT_ASC);
      
$nombre 1;
      echo 
"<u>  num\tpalabra\t\tletras diferentes</u><br />";
      foreach (
$lista_ordenada as $palabra) {
         echo 
"|  ".$nombre."\t".$palabra['pal']."\t\t".$palabra['lev']."<br />";
         
$nombre++;
      }
   } else {
   
// No se ha encontrado ninguna palabra
      
echo "No se ha encontrado ninguna palabra.<br />";
   }
}
echo 
"</pre>";
?>
__________________
LA MUERTE ESTÁ TAN SEGURA DE VENCER QUE NOS DA TODA UNA VIDA DE VENTAJA

Etiquetas: similar, aportes, busquedas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 16:40.