質問

Burrows and Wheeler Paperのブロックソートアルゴリズムを読んでいます。これはアルゴリズムのステップ:

s = abracadabraと仮定します

n単語w [0、...、n -1]の配列wを初期化します。これにより、w [i]が文字s '[i、...、i + k -1]を含むように、整数が比較されるように配置されました。この言葉は、Kキャラクターの文字列の辞書的比較に同意します。文字を言葉に詰めることには2つの利点があります。アラインドされたメモリアクセスを使用して、2つのプレフィックスを一度にKバイトを比較できるようにし、多くの遅いケースを排除できます

(ノート: S' オリジナルです S kで EOF それに追加されたキャラクター、Kはマシンワードに収まる文字の数です(私は32ビットマシンにいるので、 k=4)

EOF = '$'

私が間違っている場合は私を修正してください:

S'= abracadabra$$$$  
W= abra brac raca acad cada adab dabr abra bra$ ra$$ a$$$

次に、アルゴリズムは、の接尾辞配列を並べ替えなければならないと言います S (名前v)、by 配列へのインデックス付け W.

インデックスを作成することで、どのように接尾辞を並べ替えることができるかを完全には理解していません W。たとえば、ソートのある時点で、2つの接尾辞が得られるとします。 ij, 、そしてあなたはそれらを比較する必要があります。あなたがインデックスを付けているので W, 、当時4文字をチェックしています。
両方とも同じ最初の4文字を持っているとします。次に、次の4文字のサフィックスごとに確認する必要があり、各接尾辞の4番目の位置からアクセスしてそれを行います。 W。これは正しいですか?この「キャラクターを言葉に詰める」ことは本当にスピードアップしますか?

役に立ちましたか?

解決

質問でそれを説明する方法は完全に正確です。そして、はい、あなたが言ったように、それは一度に4人のキャラクターを比較するので、それは物事をスピードアップします。

ただし、2つの発言が行われます。

  1. 接尾辞IとJを比較すると、例のように、実際にw [i]とw [j]エントリを比較します。この結果は、文字s [i..i+3]とs [j..j+3]の4倍を辞書的に比較した場合と同じであるため、3つの文字比較に相当するコンピューティング時間を保存しました。そして、はい、結果が2つの象限が同一であることを示している場合、w [i+1]とw [j+1]を比較し続ける必要があります。 でも: :あなたはすぐにそれをしません。彼らのアルゴリズムの仕組みは、基数の種類です。つまり、最初の比較の直後に接尾辞をバケツに入れ(おそらく同じバケツに入れます)、その後、バケツを内部的に並べ替えて再帰的に並べ替えます。
  2. バロウズとホイーラーによって元の論文で説明されているアルゴリズム(あなたが引用する;コピーがあります ここ たとえば、1994年からの)は、最適なサフィックスアレイ構造アルゴリズムではありません。第一に、2003年にいくつかのO(n)で、直接的な建設方法が発見されました。第二に、それ以来、実装のさらに多くの改善が行われました。 1994年の論文の中核は、変換自体が生成される正確な方法ではなく、文字列圧縮の基礎として巣穴駆動の変換を使用するというアイデアです。

他のヒント

配列vは接尾辞アレイではなく、Wへのインデックスの配列です。ソートが完了すると、vはインデックスをwに保持する必要があります。

V[i] <= V[j]

それから

 W[V[i]] <= W[V[j]].

私は正しいと言ったことを願っています:)それらを正確に一致させることは問題ではなく、どちらの順序も問題ありません。ポイントは、逆変換を適用すると、元の文字列を回復するためにWを回復できる必要があり、Wの同一の要素がそれで問題を引き起こすことはないということです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top