3

現在、Javaでハフマンアルゴリズムに基づくプログラムの実装に取り​​組んでおり、エンコードされたコンテンツをファイルに出力する必要がある段階にあります。デコードに必要なヘッダーとeofを実装する方法について少し混乱しています。現時点での私のヘッダーには、入力ファイルとその頻度から発生するすべての一意の値がありますが、一部の記事では、0または1でノードを表し、次に頻度を表します(少し戸惑っています)シンボルが何であるかを述べていないので)。

また、私が理解しているEOFの場合、シンボルのようにエンコードして読み取られ、デコードされますが、どのような値を使用できるのかわかりません。重みを1にする必要があることはわかっていますが、実際にファイルに含まれないようにする方法がわかりませんでした。

4

2 に答える 2

5

私は割り当てのためにこれを一度行わなければなりませんでした、そしてこれは私たちが使用したアプローチです。

ヘッダーのエンコードは、(頻度ではなく)ツリーの構造をエンコードするために0と1を使用して行われました。「0」はツリーに沿って移動することを示し、「1」はリーフノードにいることを示します。これにより、ツリーを一意にエンコードする一種のプレオーダートラバーサルが発生しました。

たとえば、(((ab)c)(de))のようなツリーは、「0001 a1 b1 c01 d1 e」としてエンコードされます。ここで、a、b、c、d、eはASCII形式です。

グラフィカルな形式のツリーは次のとおりです。

     / \
   /\   /\
 /\  c d  e
a  b 

EOFの場合、ファイルの最後の3ビットを使用して、最後の2バイトのうち読み取る必要のあるバイト数を指定しました。最後のバイトを読み取ったら(つまり、最後から2番目のバイトで作業していました)、最後の3ビットをチェックしました。読み取るビット数から6を引いた数をエンコードしました。つまり、「読み取り(6ビット)して他のすべてを破棄する110101xxxxxxx000」という意味です。「 (7ビット)を読み取り、残りを破棄する」などを意味します。1101011101011xxxxxx0011101011

このようにすることで、EOFを示す特別な値を設定する必要がなくなり、ファイルを一度に1バイトずつ読み取ることができました(実際には、作業場所の1バイト前に読み取る必要がありました)。

(EOFについては、あなたの記事を読んでいないので、私たちのアイデアがあなたのアプローチで機能するかどうかはわかりません。)

于 2011-11-20T02:02:07.367 に答える
2

ハフマン符号化は、文字のシーケンスからハフマンツリーを作成する方法と、それをビットのシーケンスに符号化する方法を指定します。

ツリーをどのようにエンコードするか、または読み取るビット数を正確に把握する方法は指定されていません。ファイルに保存できるのはバイト全体のみであるため、ビットの正確な数は問題です。したがって、どのビットで終了するかを正確に把握する方法が必要です。

ツリーをエンコードするには、いくつかのオプションがあります。それらの1つは、各文字のカウントを記録し、デコーダーにそこからツリーを再構築させることです。他のオプションは、たとえば0-1アプローチ管理を使用して(そして私はあなたが言及した記事を想定しています)、何らかの方法でツリーを直接エンコードすることです。

次に、ツリーをまったく必要としない適応形ハフマン符号化がありますが、より複雑です。

いつ終了するかを決定するために、ファイルに文字の総数を書き込み、それを使用していつ停止するかを決定できます。または、文字数を使用してツリーをエンコードした場合は、この数を無料で取得できます。

もう1つのオプションは、EOF文字を使用することです。これはハフマンツリーにある文字ですが、通常の値をエンコードしていません。バイトをエンコードしていると仮定すると、257番目の値として想像できます。( EOFトークンには、ゼロバイトなどの通常の値を使用できますが、入力ファイルに存在しないことを絶対に確認する必要があります。)

于 2011-11-20T02:31:33.933 に答える