序文:学校の年次データ構造コースの日です。データ構造コースの内容について、学校の仲間からの熱心な「問い合わせ」に耐えられません。以前のデータ構造コースで行ったことをここに記載します。 。結論として
ハフマンコーデック
私がクラスで選んだトピックは、ハフマンコーデックでした。これは、通常使用する解凍ソフトウェアに似ており、大きなファイルを小さなファイルに圧縮できます。
デザインの狙い
データ構造コース設計の主な目的は、学生がアプリケーションシステム設計の方法と手順をさらに習得し、システム分析、システム設計、プログラミングとデバッグ、書き込みを通じて、ソフトウェア開発における典型的なデータ構造のアプリケーションを柔軟に使用し、深く理解できるようにすることです。問題の分析と解決の能力をさらに向上させ、プログラミングのレベルを向上させるための実験報告など。
デザインコンテンツ
ハフマンコーデック
は、情報通信にハフマンコーディングを使用します。これにより、チャネルの使用率が大幅に向上し、情報の送信時間が短縮され、送信コストが削減されます。ハフマンエンコーダ/デコーダを実装するコードを作成するには、送信するデータをエンコードシステムで事前にエンコードする必要があります。そして、受信側で送信されたデータをデコード(回復)します。
具体的な機能は次のとおりです。
- ハフマンツリーを構築する:ファイル(xxx.souce)を読み取り、ファイル内の文字の頻度をカウントし、これらの文字の頻度を重みとして使用してハフマンツリーを構築します。
- エンコーディング:確立されたハフマンツリーを使用して、各文字のハフマンエンコーディングを取得し、テキストをエンコードしてから、エンコーディング結果を出力してファイル(xxx.code)に保存します。
- デコード:確立されたハフマンツリーを使用して、ファイル内のコード(xxx.code)をデコードし、デコード結果を出力して、ファイル(xxx.decode)に保存します。
- ビット操作を使用してファイルを圧縮および解凍します。(オプション)
アウトラインデザイン
圧縮および解凍インターフェース:
これはJavaFxで記述された単純なグラフィカル・インターフェースであり、ファイルの圧縮と解凍を選択できます。選択した後、選択したファイルを圧縮または解凍できます。
圧縮機能
圧縮機能は、ファイル内の各要素に応じて重み(つまり、要素が出現する回数)に応じてハフマンツリーを形成し、形成されたハフマンツリーをトラバースしてハフマンコードを形成し、形成されたハフマンコードビット圧縮(つまり、8ビットごとに1バイトを形成)、最後にビット単位の圧縮コード、ハフマンツリーの要素、これらの要素に対応する重み、およびファイルの名前形式を圧縮に書き込みます次回の解凍操作を容易にするためのファイル。
解凍機能
解凍機能のプロセスは、圧縮プロセスに似ています。また、ファイルを読み取り、圧縮中にファイルに格納されている情報を読み取り、最初に読み取りバイト配列に従って、次に読み取りデータに従ってハフマンコードを復元します。ハフマンツリーはハフマンツリーを再作成し、次にハフマンツリーをトラバースしてハフマンコードセットを再形成し、ハフマンコードをトラバースして文字配列を再形成し、文字配列に従って元のバイト配列を復元し、最後に出力を使用しますバイト配列を元のファイルに復元して、圧縮前にファイルを取得できます。
機能ブロック図
各モジュールの詳細な機能説明
圧縮
圧縮するファイルを読み取る:圧縮
する選択したファイルを読み取り、その中のデータをバイト配列の文字配列に変換し、最後に文字配列を返します。文字
の出現回数をカウントします。
文字内の各文字をカウントします。ファイルから読み取られた配列出現回数、マップセットに格納;
ハフマンツリーの作成:
カウントされた文字時間のセットに従ってハフマンツリーを作成;
ハフマンツリーをトラバース:
ハフマンツリーが作成された後、ハフマンツリートラバースして各リーフノードのコードを取得し、これらのコードをコレクションに格納します。
フォームハフマンコード:
リーフノードのコードに従って文字配列をトラバースしてハフマンコードを取得し、コード文字列を返します。
圧縮します。ハフマンコード:
ハフマン符号化文字列をビット単位でバイト配列に圧縮し、バイト配列を返します。
圧縮されたハフマン符号化をファイルに保存します。
ハフマン符号化が圧縮ファイル内に圧縮された後、返されたバイト配列を格納します。
解凍
圧縮ファイル
の読み取り:解凍するファイルを読み取り、ハフマンツリー、ハフマン符号化バイト配列、元のファイル名と形式を返します。
ハフマン符号化を復元します。
ハフマン符号化ワードを読み取ります。セクション配列を文字列に再度変換します。つまり、バイトを復元します。バイナリ文字列に;
ハフマンツリーを再作成します:
ハフマンツリーの読み取りリーフと重量情報に従ってハフマンツリーを再作成します;ハフマンツリー
をトラバースしますマンツリー:
ハフマンツリーをトラバースしてリーフのコードを取得し、ハフマンコード文字列を使用して元の文字配列を取得し、支払い配列をバイト配列に変換して返します。
元のファイルデータを復元します。
返されたバイト配列と、前に読み取った元のファイルの形式と名前に従って、を再作成します。ファイルに情報を書き込んで、元のファイル情報を復元します。
きめ細かなデザイン
関数呼び出しの関係
各機能のデータフローチャート
キーの設計とコーディング
ハフマンコードのビット単位の圧縮
public static byte[] codeZip(String code){
int len;
if (code.length()%8==0){
len = code.length()/8;
}else{
len = code.length()/8+1;
}
byte[]bytes = new byte[len];
int index = 0;
for (int i = 0;i < code.length();i += 8){
String strByte;
if (i+8>code.length()){
strByte = code.substring(i);
}else{
strByte = code.substring(i,i+8);
}
//Integer.parseInt(strByte, 2)方法的作用是输出二进制strByte数变成十进制后的数
//如:1010变为十进制后为10
bytes[index] = (byte) Integer.parseInt(strByte,2);
index++;
}
return bytes;
}
ハフマン符号化を文字配列に復元する操作
public static char[] enCode(String code, Map<String,Character> map){
List<Character> list = new ArrayList<>();
for(int i = 0; i < code.length(); ) {
int count = 1;
boolean flag = true;
Character b = null;
String key = null;
while(flag) {
if (i+count<=code.length()){
key = code.substring(i, i + count);
}else{
//如果到了结尾而且key还找不到匹配的值,就对key进行补零的操作
key="0"+key;
System.out.println(key);
}
b = map.get(key);
if (b == null) {
++count;
} else {
flag = false;
}
}
list.add(b);
i+=count;
}
char[]chars = new char[list.size()];
for (int i=0;i<chars.length;i++){
chars[i] = list.get(i);
}
return chars;
}
テストデータと実行結果
通常のテストデータと実行結果
txtファイルを解凍します
圧縮前:
圧縮:
解凍後:
コンソール出力:
ハフマンツリーノード情報、ハフマン符号化、ハフマン符号化長さ、圧縮率などを出力します。
mp4ファイルを解凍します
解凍する前に:
圧縮後:
解凍後:
コンソール出力:
ハフマンツリーノード情報、ハフマン符号化、ハフマン符号化長さ、圧縮率などを出力します。
異常なテストデータと実行結果
大きなファイルを圧縮する
エラー:
これは、Java仮想マシンのヒープメモリがエラーを報告するには不十分であるためです。これについて文句を言う必要があります。急いで実行し、文字列タイプのエンコーディングを直接使用したため、大きすぎるファイルを圧縮できませんでした...
空のファイルを圧縮する
エラー:
これは、空のファイルの判断が追加されていないためです(誰も空のファイルを圧縮しないと思ったので...まあ、誰かが空のファイルを圧縮します)
デバッグ状況、設計スキル、および経験
提案を改善する
現在のハフマンコーデックは基本的に実験に必要な機能を実装していますが、次のように、まだいくつかの欠点と改善の余地があります。
- 空のファイルを圧縮するときにコンパイラがエラーを報告しないように、空のファイルの判断を追加します。
- 大きなファイルを圧縮する際のJava仮想マシンのメモリオーバーフローの解決策は、IOストリームを使用することで解決でき、制限を設定できます。10Mのデータを読み込むと、ファイルの読み込み中にファイルデータ操作が実行されます。ファイルデータ操作が完了すると、圧縮ファイルに操作データが出力され、10Mを読み込んだ後、上記の処理、つまりセグメント化された読み取りと書き込みに従って読み取り操作が続行されます。このようにして、仮想マシンのメモリ占有を大幅に削減することができ、仮想マシンによるデータ処理の速度を加速することができます。
- JavaFxによって記述されたインターフェースの美化は、まだ改善する必要があります。進行状況バーを追加して、圧縮のどのステップが進行中であるかを示すことができます。これにより、圧縮と解凍のプロセスをより直感的に体験できます。誰もがソフトウェアを見ることができます。ランタイムコンソールの出力。
経験
このクラスから多くのことを学びました。クラスで学んだハフマンツリーの知識を応用して練習し、プログラムを作成しました。コードを使用してハフマンツリーを作成する方法と、作成後にハフマンツリーを使用する方法を知っていました。ハフマンツリーはハフマン符号化に変換されました。授業の前に、ハフマン符号化に変換してファイルに保存するとファイルの圧縮が実現すると思いましたが、プログラムを書いたところ、ファイルが大きくなることがわかりました。圧縮要件を満たすためには、取得したハフマンコードに対してビット単位の圧縮を実行する必要もあります。ビット単位の圧縮では、「01」ハフマンコードを8ビットに従って1バイトに再圧縮します。理論的には、データ繰り返し率が非常に高いです。ファイルを圧縮するとメモリを7〜8倍減らすことができるので、ファイルを圧縮できます。解凍するには、ハフマンツリーの情報をファイルに記録する必要があります。ハフマンツリーを復元します。
参照
参照のほとんどは学校の教科書です...私はそれらのほとんどをBaiduで直接チェックしているようですが...
[1] WangShuyan。データ構造とアルゴリズム。北京: HigherEducationPress。2019
[2]Wang Shuyan。データ構造とアルゴリズム。Beijing:People’s Posts
andTelecommunicationsPress。2013[3]GengGuohua。データ構造C言語の説明。北京:高等教育教育プレス
.2011 [4] YanWeimin。データ構造。北京:TsinghuaUniversityPress。2012
[5]Wang Shuyan。C言語プログラミングチュートリアル。北京:People's Posts andTelecommunicationsPress。2014
やっと
プロジェクトのアドレスは次のとおりです
。Githubアドレス:https
://github.com/guanchanglong/HuffmanEncoder/tree/masterコードを読むときに星を付けてください^ _ ^、ご尽力いただきありがとうございます。
PS:私の個人ブログにアクセスして、より多くのコンテンツを表示することもでき
ます。個人ブログのアドレス:Xiaoguanクラスメートのブログ