アナグラムと部分一致を見つけるためのモバイルアプリを作成しています。計算能力はそれほど多くなく、効率が重要であるため、モバイルは重要です。
アルゴリズムは、繰り返しを含む任意の数の文字を受け取り、すべての文字を1回だけ使用して、その文字から構成される最長の単語を検索します。私はまた、トップの結果をすばやく見つけることに興味があり、Nが満たされている限り、ボトム(短いもの)にはあまり関心がありません。例えば:
STACK => stack, tacks, acts, cask, cast, cats…
私はいくつかのグーグルを行い、いくつかのアルゴリズムを見つけました。そして、効率的だと思ったものを思いつきましたが、私が望むほど効率的ではありません。
ソートされたキーをそのキーを生成する実際の単語にマップするルックアップ辞書が事前に作成されています。
"aelpp" => ["apple", "appel", "pepla"]
キーの長さに基づいて、各辞書をさらに別の辞書に分割しました。したがって、5文字の長さのキーはある辞書にあり、6文字のキーは別の辞書にあります。これらの各ディクショナリは配列内にあり、インデックスはディクショナリで見つかったキーの長さです。
anagramArray[5] => dictionary5
dictionary5["aelpp"] => ["apple", "appel", "pepla"]
私のアルゴリズムは、入力単語 " lappe
"を取得することから始まり、それをソートします。
"lappe" => "aelpp"
ここで、最大5文字の内容を持つ辞書ごとに、比較して引き出します。擬似コードは次のとおりです。
word = input.sort
for (i = word.length; i > 0; i--)
dictionaryN = array[i]
for (key in dictionaryN)
if word matches key
add to returnArray
end
end
if returnArray count > N
break
end
end
returnArray.sort by longest word, alphabetize
辞書には約17万語しか含まれていませんが、12文字の入力で検索に最大20秒かかります。私のmatch
方法では、キーから正規表現を作成します。
"ackst" => /a.*c.*k.*s.*t.*/
たとえば、acst
(acts)などの4文字のキーは、次のackst
理由で(stack)と一致します。
"ackst" matches /a.*c.*s.*t.*/
私は他のアプリがはるかに短い時間で同じことをするのを見てきました、そして私のアプローチがゴミなのか、それとも単に微調整が必要なのか疑問に思います。
最大長でソートされた単語から上位N個のアナグラムを生成するための最大の計算効率を得るにはどうすればよいですか?