質問

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

  • fck のための一致です fc kopenhavn それは単語の最初の文字と一致するからです。 fhk 一致しないだろう。
  • fco 一致すべきではありません fc kopenhavn 誰もFCコペンハウンをfcoと略すことはないからである。
  • irl のための一致です in real life.
  • ifk のための一致です ifk goteborg.
  • aik のための一致です allmanna idrottskluben.
  • aid のための一致です allmanna idrottsklubben.これは実際のチーム名の略語ではありませんが、スウェーデン語の略語がどのように形成されているかについてドメイン固有の知識を適用しない限り、それを除外するのは難しいと思います。
  • manu のための一致です manchester united.

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

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

役に立ちましたか?

解決

これは私が作成したいくつかの余分なものを含むすべてのテストに合格します。再帰を使用します。ここに私が使用したルールがあります:

  • 省略形の最初の文字は、省略形の最初の文字と一致する必要があります テキスト
  • 残りの省略形(abbrevから最初の文字を引いたもの)は、以下の省略形でなければなりません:

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

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

他のヒント

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

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

キャレットは、略語の最初の文字が単語の最初の文字と一致することを確認します。

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

これは正しく一致します fckFC 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

@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

あなたはあなたの論理を定義する必要があります、あなたは盲目的に略語を見つけることができません。

あなたのアルゴリズムは単純なようです-略語はすべての大文字の連結です。だから:

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

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

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')
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top