最適な圧縮を提供するプレフィックス部分文字列を見つけます
-
02-07-2019 - |
質問
問題:
文字列のリストが与えられたら、一致するすべての文字列の先頭から減算され、エスケープバイトに置き換えられた場合に、最短の合計長になる部分文字列を見つけます。
例:
" foo"
、" fool"
、" bar"
結果は次のとおりです。" foo"文字列" \ 0"
、" \ 0l"
、" bar"
および合計長9のベース文字列としてバイト。 " \ 0"
はエスケープバイトです。元の文字列の長さの合計は10なので、この場合は1バイトしか保存しません。
単純なアルゴリズムは次のようになります。
for string in list
for i = 1, i < length of string
calculate total length based on prefix of string[0..i]
if better than last best, save it
return the best prefix
これで答えが得られますが、O((n * m)^ 2)のようなもので、高すぎます。
解決
プレフィックスツリーのフォレストを使用(トライ)...
f_2 b_1
/ |
o_2 a_1
| |
o_2 r_1
|
l_1
その後、エスケープ文字で置き換えられる(depth * frequency)
を最大化することで、最良の結果を見つけて保証できます。分岐深さ優先検索を最大にして検索を最適化できます。
複雑さ:O(C)、コメントで述べたように、それを構築し、最適なものを見つけるために、それは依存します。最初の要素の頻度(O(A)-Aは言語のアルファベットのサイズ)を注文すると、より多くの分岐を切り取ることができ、準線形時間を得る可能性が高くなります。
これは明確だと思います。書きませんが、宿題とは何ですか? ;)
他のヒント
リストを並べ替えることから始めます。次に、最初の文字を次の文字列の最初の文字と比較して、文字列から文字列に移動します。マッチしたら、次の文字を確認します。これまでで最良の結果を追跡する方法を考案する必要があります。
まあ、最初のステップはリストをソートすることです。次に、リストを1回通過し、各要素を前の要素と比較して、最長の2文字、3文字、4文字などの実行を追跡します。その場合、数字は15の4文字プレフィックスよりも優れた20の3文字プレフィックスです。