ゴールポストの動きに対する応答は次のとおりです (「近い将来単語の区切り記号が必要になるため、おそらく正規表現が必要です」)。
このメソッドは、テキストを 1 回解析して、すべての「単語」のリストを取得します。各単語は対象語の辞書で調べられ、対象語であればカウントされます。かかる時間は O(P) + O(T) です。ここで、P は段落のサイズ、T はターゲットの単語数です。私の Aho-Corasick ソリューションを除く、これまでの他のすべてのソリューション (現在受け入れられているソリューションを含む) は O(PT) です。
def counts_all(targets, paragraph, word_regex=r"\w+"):
tally = dict((target, 0) for target in targets)
for word in re.findall(word_regex, paragraph):
if word in tally:
tally[word] += 1
return [tally[target] for target in targets]
def counts_iter(targets, paragraph, word_regex=r"\w+"):
tally = dict((target, 0) for target in targets)
for matchobj in re.finditer(word_regex, paragraph):
word = matchobj.group()
if word in tally:
tally[word] += 1
return [tally[target] for target in targets]
finditer バージョンはストローマンです。findall バージョンよりもはるかに低速です。
標準化された形式で表現され、単語区切り記号で補強された、現在受け入れられている解決策を次に示します。
def currently_accepted_solution_augmented(targets, paragraph):
def tester(s):
def f(x):
return len(re.findall(r"\b" + x + r"\b", s))
return f
return map(tester(paragraph), targets)
これは閉鎖で船外に出て、次のように減らすことができます。
# acknowledgement:
# this is structurally the same as one of hughdbrown's benchmark functions
def currently_accepted_solution_augmented_without_extra_closure(targets, paragraph):
def tester(x):
return len(re.findall(r"\b" + x + r"\b", paragraph))
return map(tester, targets)
現在受け入れられている解のバリエーションはすべて O(PT) です。現在受け入れられている解決策とは異なり、単語区切り文字を使用した正規表現検索は、単純な と同等ではありませんparagraph.find(target)
。この場合、re エンジンは「高速検索」を使用しないため、単語区切り文字を追加すると、低速から非常に低速に変更されます。