2010-12-06 11 views
5

Tengo dos listas de palabras, supongamos LIST1 y LIST2. Quiero comparar LIST1 contra LIST2 para encontrar los duplicados, pero también debe encontrar el plural de la palabra así como la forma ing. Por ejemplo.Comparar palabras, también hay que buscar plurales e ing?

Supongamos que LIST1 tiene la palabra "cuenta", y LIST2 tiene las palabras "cuentas, contabilidad" Cuando lo comparo, el resultado debe mostrar dos coincidencias para la palabra "cuenta".

Lo estoy haciendo en PHP y tengo la LISTA en las tablas de mysql.

+0

Sé que este es un hilo antiguo, pero acabo de agregar una respuesta, mira lo que piensas si tienes un minuto. – quickshiftin

Respuesta

0

Lo que yo haría es tomar su palabra y compararla directamente con LIST2 y al mismo tiempo eliminar su palabra de cada palabra que está comparando buscando una palabra más, s, es para denotar una palabra plural o ing (esto debería ser lo suficientemente preciso). Si no vas a tener que generar un algoritmo para formar plurales de palabras, ya que no es tan simple como añadir un S.

Duplicate Ending List 
s 
es 
ing 

LIST1 
Gas 
Test 

LIST2 
Gases 
Tests 
Testing 

Ahora comparar Lista1 a Lista2. Durante el mismo ciclo de comparación haga una comparación directa con los ítems y uno donde la palabra, de la lista 1, se elimine de la palabra actual que está viendo en la lista 2. Ahora solo verifique que este resultado se encuentre en la Lista de finalización duplicada.

Espero que tenga sentido.

0

El problema es que, al menos en inglés, los plurales no son todas las extensiones estándar, ni son participios presentes. Puede hacer una aproximación usando todas las palabras +'ing' y +'s', pero eso dará falsos positivos y negativos.

Puede manejarlo directamente en MySQL si lo desea.

SELECT DISTINCT l2.word 
    FROM LIST1 l1, LIST l2 
    WHERE l1.word = l2.word OR l1.word + 's' = l2.word OR l1.word + 'ing' = l2.word; 
5

Se puede utilizar una técnica llamada porter stemming a asignar cada entrada de la lista a su madre, y luego comparar los tallos. Se puede encontrar una implementación del algoritmo Porter Stemming en PHP here o here.

+0

+1 por iniciarme en Porter Stemming research :) – RobertPitt

+0

Nice. Nunca antes había oído hablar de esa técnica. – Veign

+0

Es por eso que acaba de desaparecer en mi lista de investigación. es bastante simple de lo que puedo deducir – RobertPitt

0

Esta función generará el plural de una palabra.

http://www.exorithm.com/algorithm/view/pluralize

Algo similar se podría escribir de gerundios y participios presentes (formas ING)

+0

Gracias Mike C este script fue simple y fácil de entender y me ayudó a tener una idea – daron

0

Se podría considerar el uso de la clase Doctrine Inflector en conjunción con un stemmer para esto.

Aquí es el algoritmo en un nivel alto

  1. de Split cadena de búsqueda en los espacios, las palabras de proceso individual
  2. minúsculas la palabra de búsqueda
  3. eliminar caracteres especiales
  4. singularizan, reemplace differing portion con comodín (' % ')
  5. Vástago, reemplace la porción diferente con comodín ('% ')

Ésta es la función que armó

/** 
* Use inflection and stemming to produce a good search string to match subtle 
* differences in a MySQL table. 
* 
* @string $sInputString The string you want to base the search on 
* @string $sSearchTable The table you want to search in 
* @string $sSearchField The field you want to search 
*/ 
function getMySqlSearchQuery($sInputString, $sSearchTable, $sSearchField) 
{ 
    $aInput = explode(' ', strtolower($sInputString)); 
    $aSearch = []; 
    foreach($aInput as $sInput) { 
     $sInput = str_replace("'", '', $sInput); 

     //-------------------- 
     // Inflect 
     //-------------------- 
     $sInflected = Inflector::singularize($sInput); 

     // Otherwise replace the part of the inflected string where it differs from the input string 
     // with a % (wildcard) for the MySQL query 
     $iPosition = strspn($sInput^$sInflected, "\0"); 

     if($iPosition !== null && $iPosition < strlen($sInput)) { 
      $sInput = substr($sInflected, 0, $iPosition) . '%'; 
     } else { 
      $sInput = $sInput; 
     } 

     //-------------------- 
     // Stem 
     //-------------------- 
     $sStemmed = stem_english($sInput); 

     // Otherwise replace the part of the inflected string where it differs from the input string 
     // with a % (wildcard) for the MySQL query 
     $iPosition = strspn($sInput^$sStemmed, "\0"); 

     if($iPosition !== null && $iPosition < strlen($sInput)) { 
      $aSearch[] = substr($sStemmed, 0, $iPosition) . '%'; 
     } else { 
      $aSearch[] = $sInput; 
     } 
    } 

    $sSearch = implode(' ', $aSearch); 
    return "SELECT * FROM $sSearchTable WHERE LOWER($sSearchField) LIKE '$sSearch';"; 
} 

Qué me encontré con varias cadenas de prueba

Input String: Mary's Hamburgers 
SearchString: SELECT * FROM LIST2 WHERE LOWER(some_field) LIKE 'mary% hamburger%'; 

Input String: Office Supplies 
SearchString: SELECT * FROM LIST2 WHERE LOWER(some_field) LIKE 'offic% suppl%'; 

Input String: Accounting department 
SearchString: SELECT * FROM LIST2 WHERE LOWER(some_field) LIKE 'account% depart%'; 

Probablemente no es perfecto, pero es un buen comienzo de todos modos! Donde caerá es cuando se devuelven múltiples coincidencias. No hay lógica para determinar la mejor coincidencia. Ahí es donde entran cosas como MySQL fulltext y Lucene. Pensando en ello un poco más, ¡usted podría ser capaz de usar levenshtein para clasificar múltiples resultados con este enfoque!

Cuestiones relacionadas