2011-09-07 16 views
8

Sto provando a sviluppare un algoritmo python per verificare se una stringa potrebbe essere un'abbreviazione per un'altra parola. Per esempioControlla se una stringa è una possibile abbreviazione di un nome

  • fck è una partita per fc kopenhavn perché corrisponde ai primi caratteri della parola. fhk non corrisponde.
  • fco non dovrebbe corrispondere a fc kopenhavn perché nessuno irl avrebbe abbreviato FC Kopenhavn come FCO.
  • irl corrisponde a in real life.
  • ifk è una partita per ifk goteborg.
  • aik è una corrispondenza per allmanna idrottskluben.
  • aid è una partita per allmanna idrottsklubben. Questo non è un nome un'abbreviazione vera squadra, ma credo che è difficile escludere a meno che non si applica la conoscenza specifica del dominio su come abbreviazioni svedese si formano.
  • manu corrisponde a manchester united.

E 'difficile descrivere le regole esatte dell'algoritmo, ma spero che la mia esempi mostrano quello che sto cercando.

Aggiornamento Ho fatto un errore nel mostrare le stringhe con le lettere corrispondenti maiuscole. Nello scenario reale, tutte le lettere sono minuscole, quindi non è così facile come basta controllare quali lettere sono maiuscole.

+0

Così si vuole vedere se la stringa corrisponde solo le lettere maiuscole a quelle corde? Se è così, prova a scrivere qualcosa per quello che fa: prende solo le lettere maiuscole delle tue cose complete e le schiaffa in un dizionario (come le chiavi con la versione completa come valori), e poi è facile cercarlo. Così com'è, non hai davvero fatto una domanda ... –

+0

La cosa migliore che potrei pensare è estrarre tutte le lettere maiuscole, convertire la stringa breve in maiuscolo e poi fare test di uguaglianza. –

+0

Semi-OT: ManU può essere visto come un insulto per i fan di ManUnited, sebbene sia ampiamente usato come abbrev in paesi non inglesi. –

risposta

8

Questo supera tutti i test, inclusi alcuni extra che ho creato. Usa la ricorsione. Ecco le regole che ho usato:

  • La prima lettera della sigla deve corrispondere la prima lettera del testo
  • Il resto della sigla (l'abbrev meno la prima lettera) devono essere un'abbreviazione per:

    • rimanenti parole o
    • il testo rimanente partendo da qualsiasi posizione nella prima parola.

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

Dannato, bastonato per 30 secondi :) +1 –

+0

Siamo spiacenti, tutte le stringhe dovrebbero essere tutte in minuscolo. Tutto è in minuscolo nell'originale. –

0

vostro algoritmo sembra semplice - la sigla è la concatenazione di tutte le lettere maiuscole. così:

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

Si potrebbe utilizzare 'string.ascii_uppercase' –

+0

che sarebbe meglio:/ – Dominik

0

Questo potrebbe essere abbastanza buono.

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

che non è corretto, per esempio prova 'print is_abbrevation ('fkc', 'FC Kopenhavn')' –

4

Ecco un modo per realizzare ciò che ti sembra di voler fare

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

L'accento circonflesso fa in modo che il primo carattere della sigla corrisponde al primo carattere della parola, dovrebbe essere vero per la maggior parte delle abbreviazioni.

Modifica: Il nuovo aggiornamento ha leggermente modificato le regole. Utilizzando "(|.*\s)" invece di ".*" personaggi del sigla corrisponderà solo se sono uno accanto all'altro, o se il carattere successivo appare all'inizio di una nuova parola.

Corrisponde correttamente a fck con FC Kopenhavn, ma a fco no. Tuttavia, la corrispondenza aik con allmanna idrottskluben sarà non lavoro, in quanto ciò richiede la conoscenza del linguaggio svedese e non è così banale da fare.

Ecco il nuovo codice con la modifica minore

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

@Ocaso Protal detto in commento how should you decide that aik is valid, but aid is not valid? e ha ragione.

L'algo che è venuto in mente è quello di lavorare con word threshold (numero di parole separate da uno spazio).

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 

è necessario definire la logica, non è possibile trovare abbreviazione ciecamente.

Problemi correlati