14

文字列が別の単語の略語であるかどうかを確認するための Python アルゴリズムを開発しようとしています。例えば

  • fckfc kopenhavn単語の最初の文字に一致するため、 に一致します。fhk一致しません。
  • fcofc kopenhavnFC Kopenhavn を FCO と略す人はいないため、一致しないはずです。
  • irlに一致しin real lifeます。
  • ifkに一致しifk goteborgます。
  • aikに一致しallmanna idrottsklubenます。
  • aidに一致しallmanna idrottsklubbenます。これは実際のチーム名の省略形ではありませんが、スウェーデンの省略形がどのように形成されるかについてドメイン固有の知識を適用しない限り、除外するのは難しいと思います。
  • manuに一致しmanchester unitedます。

アルゴリズムの正確なルールを説明するのは難しいですが、私の例が私が求めているものを示していることを願っています.

更新一致する文字を大文字にして文字列を表示するのを間違えました。実際のシナリオでは、すべての文字が小文字であるため、どの文字が大文字であるかを確認するだけでは簡単ではありません。

4

5 に答える 5

14

これは、私が作成したいくつかの追加を含むすべてのテストに合格します。再帰を使用します。これが私が使用したルールです:

  • 略語の最初の文字は、テキストの最初の文字と一致する必要があります
  • 残りの略語(略語から最初の文字を引いたもの)は、次の略語である必要があります。

    • 残りの言葉、または
    • 最初の単語の任意の位置から始まる残りのテキスト 。

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
于 2011-09-07T09:28:07.337 に答える
4

@Ocaso Protalコメントで言った、how should you decide that aik is valid, but aid is not valid?そして彼は正しい。

私の頭に浮かんだアルゴは、word threshold(スペースで区切られた単語の数)で動作することです。

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

ロジックを定義する必要があり、やみくもに略語を見つけることはできません。

于 2011-09-07T10:28:14.623 に答える
4

あなたがやりたいと思っていることを達成する方法は次のとおりです

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

キャレットは、略語の最初の文字が単語の最初の文字と一致することを確認します。これは、ほとんどの略語に当てはまります。

編集:あなたの新しい更新により、ルールが少し変更されました。"(|.*\s)"略語の文字の代わりに使用すると".*"、それらが互いに隣接している場合、または次の文字が新しい単語の先頭にある場合にのみ一致します。

これは と正しく一致fckしますFC Kopenhavnが、一致しfcoません。ただし、とのマッチングは機能aikallmanna idrottsklubenませ。これにはスウェーデン語の知識が必要であり、それほど簡単ではないからです。

マイナーな変更を加えた新しいコードは次のとおりです

import re    
def is_abbrev(abbrev, text):
    pattern = "(|.*\s)".join(abbrev.lower())
    return re.match("^" + pattern, text.lower()) is not None
于 2011-09-07T10:05:03.300 に答える
0

あなたのアルゴリズムは単純に見えます-略語はすべて大文字の連結です。それで:

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()
于 2011-09-07T09:28:41.287 に答える
0

これで十分かもしれません。

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')
于 2011-09-07T09:30:00.700 に答える