20182310「データ構造とオブジェクト指向プログラミング」の実践の仕事 - エンコードされたハフマン木
コース:「データ構造とオブジェクト指向プログラミング」
クラス:1823
名前:周ドン
学生ID:20182310
王志強:教師実験
選択科目/必須:強制
1.ジョブの詳細:
文字セットで:S = {A、B、 C、D、E、F、G、H、I、J、K、L、M、nopq、R、S、T、U、V、X、W、 Y、Z}。
計算された確率構造ハフマン木に基づき、各文字の出現の統計的確率を含むファイルの26個の文字を考えます。
英語の文書とは、符号化と復号化を完了します。
要件:
(1)(など、または句読点を含めることはできません)が含まれ、英語のファイルの26個の文字を用意し、それぞれのキャラクターの統計の確率
(2)ハフマンツリー構造
英語のファイルの(3)は、符号化され、出力はコード化されましたファイル
エンコードされたファイルを復号化する(4)、デコードされた出力ファイル
(5)実験の設計と実装プロセスについてのブログ、およびソースコードの雲の広がりを書く
(6)結果のスクリーンショットは、クラウドクラスのレッスンにアップロード
2.分析とアイデア:
- 1.最初のハフマン木の概念を理解しておく必要があり、また、最適なバイナリツリーとして知られているハフマン符号(ハフマン)ツリー、重みを有するリーフノードのセットを決定するための手段、最小加重経路長を有する構成バイナリツリー。
経路長は、ルートからリーフノードと経路すべてに二分木の長さです。
そのバイナリ重み付け最小経路長に、大きな離れルートノードのリーフノードから近いルートノードにリーフノードの重量、及び小さい重量でなければなりません。 2.次のようにハフマンアルゴリズムは次のとおりです。
- 3.次にハフマン符号化を学ぶ:「0」と「1」:ハフマン符号化、ハフマンツリーによって行わ、通常の状況下で、文字コード。コーディング実装プロセスは、ノードが「0」として符号化される左側のサブツリートラバーサルの規定は、として符号化ノードを横断する権利は「1」、終了条件がエルゴード的である限り、ハフマン木として、ハフマンツリーをトラバースすることによって、非常に簡単ですリーフノードへ。
4.おそらく思考:ファイルから文字を読み取り、各キャラクタ、他の配列が存在する確率の発生頻度を算出する配列に格納することがまず必要です。
次いで、これらの2つのステップは、2次元アレイを構築するために、各文字は出現頻度に対応します。
次いで、小から大へのシーケンスを得るために、二次元配列のソート、第2の要素、方法のcompareToを書き込みます。
ハフマンツリーの構築法、再帰的配列は、次いで、最終的な和が1終了するまでサブツリーを構成する2つの要素の最小和を見つけます。
ハフマンツリーをトラバースすることによって、符号化された値は、新たな共存配列に各要素について得られました。次いで、環状方法により符号化され、符号化は、特定の復号化コードに反映される出力
3.実践と遭遇した問題と解決策:
- 1.まず、ノードを作成し、あなたはまた、左と右のノードを定義する必要があります。
- 2.第二に、コードが読み取りと書き込みのファイル、コードはこれを学び、私は瞬間をコンパイルしようとしたように、クライアントは、同じ目的でサーバーを受信する前にされています。
File file = new File("D:\\text.txt");
Reader reader = new FileReader(file);
BufferedReader bufferedReader = new BufferedReader(reader);
String temp = bufferedReader.readLine();
ここで私はあなたが以下のようにCドライブ上の私のテキストファイルは、常に問題があるだろうと、ファイルを読んだ後、コードを実行すると、ある問題が、発生しました:
私はDドライブが成功し、最終的に...解決策を見つけるためにしようとしませんでした。
書き込みファイル:
File file2 = new File("D:text.txt");
Writer writer = new FileWriter(file2);
writer.write(result1);
writer.close();
- 3.HuffmanTreeクラス:木、ならびに接合点を作成、ソートの、アレイの左の子ノード番号2の接合部は、アレイは、右の子ノードの数が-1、子供に重みを加える程度に比べて右の子としてエンコード0、1、、親ノード、リストに追加親ノードとしてコーディングの左の子を作り、古い左と右の子供たちは、リストの結び目まで、リストから削除しました点のみである(ルート)。
public static Node createTree(List<Node> nodes) {
// 只要nodes数组中有2个以上的节点
while (nodes.size() > 1) {
//进行从大到小的排序
Collections.sort(nodes);
//获取权值最小的两个节点
Node left = nodes.get(nodes.size() - 1);
Node right = nodes.get(nodes.size() - 2);
//生成新节点,新节点的权值为两个子节点的权值之和
Node parent = new Node('无', left.getWeight() + right.getWeight());
//让新节点作为两个权值最小节点的父节点
parent.setLeft(left);
left.setCodenumber("0");
parent.setRight(right);
right.setCodenumber("1");
//删除权值最小的两个节点
nodes.remove(left);
nodes.remove(right);
//将新节点加入到集合中
nodes.add(parent);
}
ときにのみ、ルートノード、
List<Node> list = new ArrayList<Node>();
Queue<Node> queue = new ArrayDeque<Node>();
//将根元素加入“队列
if (root != null) {
queue.offer(root);
root.getLeft().setCodenumber(root.getCodenumber() + "0");
root.getRight().setCodenumber(root.getCodenumber() + "1");
}
while (!queue.isEmpty()) {
//将该队列的“队尾”元素加入到list中
list.add(queue.peek());
Node node = queue.poll();
//如果左子节点不为null,将它加入到队列
if (node.getLeft() != null) {
queue.offer(node.getLeft());
node.getLeft().setCodenumber(node.getCodenumber() + "0");
}
//如果右子节点不为null,将它加入到队列
if (node.getRight() != null) {
queue.offer(node.getRight());
node.getRight().setCodenumber(node.getCodenumber() + "1");
}
}
これらは、私はおそらくステップです
4.最終的な結果: