Frage

Ich versuche, einen Python-Algorithmus zu entwickeln, um zu überprüfen, ob eine Zeichenfolge eine Abkürzung für ein anderes Wort sein könnte. Zum Beispiel

  • fck ist eine Übereinstimmung mit fc kopenhavn, da es mit den ersten Zeichen des Wortes übereinstimmt. fhk würde nicht übereinstimmen.
  • fco sollte nicht mit fc kopenhavn übereinstimmen, da niemand irl FC Kopenhavn als FCO abkürzen würde.
  • irl ist eine Übereinstimmung mit in real life.
  • ifk ist eine Übereinstimmung mit ifk goteborg.
  • aik ist eine Übereinstimmung mit allmanna idrottskluben.
  • aid ist eine Übereinstimmung mit allmanna idrottsklubben. Dies ist keine echte Abkürzung für Teamnamen, aber ich denke, es ist schwierig, sie auszuschließen, es sei denn, Sie wenden domänenspezifisches Wissen darüber an, wie schwedische Abkürzungen gebildet werden.
  • manu ist eine Übereinstimmung mit manchester united.

    Es ist schwer, die genauen Regeln des Algorithmus zu beschreiben, aber ich hoffe, meine Beispiele zeigen, wonach ich suche.

    Update Ich habe einen Fehler beim Anzeigen der Zeichenfolgen mit den übereinstimmenden Großbuchstaben gemacht. Im realen Szenario sind alle Buchstaben in Kleinbuchstaben geschrieben, sodass es nicht so einfach ist, nur zu überprüfen, welche Buchstaben in Großbuchstaben geschrieben sind.

War es hilfreich?

Lösung

Damit sind alle Tests bestanden, einschließlich einiger zusätzlicher Tests, die ich erstellt habe.Es verwendet Rekursion.Hier sind die Regeln, die ich verwendet habe:

  • Der erste Buchstabe der Abkürzung muss mit dem ersten Buchstaben von übereinstimmen der Text
  • Der Rest der Abkürzung (die Abkürzung abzüglich des ersten Buchstabens) muss eine Abkürzung für sein:

    • die restlichen Wörter oder
    • der verbleibende Text ab jede Position im ersten Wort.
      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
      

Andere Tipps

Hier ist eine Möglichkeit, das zu erreichen, was Sie anscheinend tun möchten

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

Das Caret stellt sicher, dass das erste Zeichen der Abkürzung mit dem ersten Zeichen des Wortes übereinstimmt. Dies sollte für die meisten Abkürzungen zutreffen.

Bearbeiten : Ihr neues Update hat die Regeln ein wenig geändert.Wenn Sie "(|.*\s)" anstelle von ".*" verwenden, stimmen die Zeichen in der Abkürzung nur überein, wenn sie nebeneinander liegen oder wenn das nächste Zeichen am Anfang eines neuen Wortes erscheint.

Dadurch wird der fck korrekt mit dem FC Kopenhavn abgeglichen, der fco jedoch nicht. Das Abgleichen von aik mit allmanna idrottskluben funktioniert jedoch nicht , da dies Kenntnisse der schwedischen Sprache erfordert und nicht so trivial ist.

Hier ist der neue Code mit der geringfügigen Änderung

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

@Ocaso Protal sagte im Kommentar how should you decide that aik is valid, but aid is not valid? und er hat Recht.

Das Algo, das mir in den Sinn kam, ist die Arbeit mit word threshold (Anzahl der durch Leerzeichen getrennten Wörter).

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

Sie müssen Ihre Logik definieren, Sie können die Abkürzung nicht blind finden.

Ihr Algorithmus scheint einfach zu sein - die Abkürzung ist die Verkettung aller Großbuchstaben. also:

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()

Das könnte gut genug sein.

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')

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top