2011-09-07 18 views
8

Estoy tratando de desarrollar un algoritmo de python para comprobar si una cadena podría ser una abducción para otra palabra. Por ejemploCompruebe si una cadena es una posible abreviación para un nombre

  • fck es un partido para fc kopenhavn porque coincide con los primeros caracteres de la palabra. fhk no coincidiría.
  • fco no debe coincidir con fc kopenhavn porque nadie irl podría abreviar FC Kopenhavn como FCO.
  • irl coincide con in real life.
  • ifk corresponde con ifk goteborg.
  • aik coincide con allmanna idrottskluben.
  • aid coincide con allmanna idrottsklubben. Esta no es una verdadera abreviatura de nombre de equipo, pero creo que es difícil excluirla a menos que aplique conocimiento específico de dominio sobre cómo se forman las abreviaciones suecas.
  • manu corresponde con manchester united.

Es difícil describir las reglas exactas del algoritmo, pero espero que mis ejemplos muestren lo que estoy buscando.

Actualización Cometí un error al mostrar las cadenas con las letras coincidentes en mayúscula. En el escenario real, todas las letras son minúsculas, por lo que no es tan fácil como simplemente comprobar qué letras están en mayúscula.

+0

¿Desea ver si la cadena coincide solo con las letras mayúsculas en esas cadenas? Si es así, intente escribir algo que haga eso: toma solo las letras mayúsculas de sus cosas completas y las pega en un diccionario (como las teclas con la versión completa como valores), y luego es fácil buscarlas. Tal como están las cosas, realmente no has hecho una pregunta ... –

+0

Lo mejor que se me ocurre es extraer todas las letras mayúsculas, convertir la cadena corta a mayúsculas y luego hacer pruebas de igualdad. –

+0

Semi-OT: ManU puede verse como un insulto para los fanáticos de ManUnited, aunque es ampliamente utilizado como abreviatura en países que no son ingleses. –

Respuesta

8

Esto pasa todas las pruebas, incluidas algunas más que he creado. Utiliza recursividad. Estas son las reglas que he utilizado:

  • La primera letra de la abreviatura debe coincidir con la primera letra del el texto
  • El resto de la abreviatura (la abreviatura menos la primera letra) debe ser una abreviatura para:

    • las palabras restantes, o
    • el resto del texto a partir de cualquier posición en la primera palabra.

tests=(
    ('fck','fc kopenhavn',True), 
    ('fco','fc kopenhavn',False), 
    ('irl','in real life',True), 
    ('irnl','in real life',False),  
    ('ifk','ifk gotebork',True), 
    ('ifko','ifk gotebork',False),  
    ('aik','allmanna idrottskluben',True), 
    ('aid','allmanna idrottskluben',True), 
    ('manu','manchester united',True), 
    ('fz','faz zoo',True), 
    ('fzz','faz zoo',True), 
    ('fzzz','faz zoo',False),  
    ) 

def is_abbrev(abbrev, text): 
    abbrev=abbrev.lower() 
    text=text.lower() 
    words=text.split() 
    if not abbrev: 
     return True 
    if abbrev and not text: 
     return False 
    if abbrev[0]!=text[0]: 
     return False 
    else: 
     return (is_abbrev(abbrev[1:],' '.join(words[1:])) or 
       any(is_abbrev(abbrev[1:],text[i+1:]) 
        for i in range(len(words[0])))) 

for abbrev,text,answer in tests: 
    result=is_abbrev(abbrev,text) 
    print(abbrev,text,result,answer) 
    assert result==answer 
+0

Darn, vencerme por 30 segundos :) +1 –

+0

Lo siento, se supone que todas las cadenas son minúsculas. Todo es minúsculo en el original. –

0

Su algoritmo parece simple - la abreviatura es la concatenación de todas las letras mayúsculas. tan:

upper_case_letters = "QWERTYUIOPASDFGHJKLZXCVBNM" 
abbrevation = "" 
for letter in word_i_want_to_check: 
    if letter in letters: 
     abbrevation += letter 
for abb in _list_of_abbrevations: 
    if abb=abbrevation: 
     great_success() 
+3

Podría usar 'string.ascii_uppercase' –

+0

Eso sería mejor:/ – Dominik

0

Esto podría ser suficiente.

def is_abbrevation(abbrevation, word): 
    lowword = word.lower() 
    lowabbr = abbrevation.lower() 

    for c in lowabbr: 
     if c not in lowword: 
      return False 

    return True 

print is_abbrevation('fck', 'FC Kopenhavn') 
+0

Eso no es correcto, p. intente 'imprimir is_abbrevation ('fkc', 'FC Kopenhavn')' –

4

Aquí está una manera de lograr lo que parece querer hacer

import re  
def is_abbrev(abbrev, text): 
    pattern = ".*".join(abbrev.lower()) 
    return re.match("^" + pattern, text.lower()) is not None 

El cursor se asegura de que el primer carácter de la abreviatura coincide con el primer carácter de la palabra, debe ser cierto para la mayoría de las abreviaturas

Editar: Su nueva actualización ha cambiado un poco las reglas. Al usar "(|.*\s)" en lugar de ".*", los caracteres en la abreviatura solo coincidirán si están uno al lado del otro, o si el siguiente carácter aparece al comienzo de una nueva palabra.

Esto coincidirá correctamente con fck con FC Kopenhavn, pero fco no lo hará. Sin embargo, coincidiendo aik con allmanna idrottsklubenno trabajo, ya que eso requiere conocimiento del idioma sueco y no es tan trivial de hacer.

Aquí está el código de nuevo con la modificación de menor importancia

import re  
def is_abbrev(abbrev, text): 
    pattern = "(|.*\s)".join(abbrev.lower()) 
    return re.match("^" + pattern, text.lower()) is not None 
4

@Ocaso Protal dijo en el comentario how should you decide that aik is valid, but aid is not valid? y tiene razón.

El algo que me vino a la mente es trabajar con word threshold (número de palabras separadas por espacio).

words = string.strip().split() 
if len(words) > 2: 
    #take first letter of every word 
elif len(words) == 2: 
    #take two letters from first word and one letter from other 
else: 
    #we have single word, take first three letter or as you like 

tiene que definir su lógica, no puede encontrar la abreviatura a ciegas.

Cuestiones relacionadas