用java编写哈夫曼编码实现:(1)I:初始化(Initialization)。从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树,并将它存于文件hfmTree中。 (2)E:编码(Encoding)。利用已建好的哈夫曼树(如不在内存,则从文件hfmTree中读人),对文件ToBeTran中的正文进行编码,然后将结果存入文件CodeFile中。 (3)D:译码(Decoding)。利用已建好的哈夫曼树将文件 CodeFile中的代码进行译码,结果存入文件TextFile中。 (4)P:打印代码文件(Print)。将文件CodeFile以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。 (5)T:打印哈夫曼树(Tree printing)。将已在内存中的哈夫曼树以直观的方式(树或凹入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。 【测试数据】 用下表给出的字符集和频度的实际统计数据建立哈夫曼树,并实现以下报文的编码和译码:"THIS PROGRAM IS MY FAVORITE"。 字符 A B C D E F G HI J K L M 频度186 64 13 22 32 103 21 15 47 57 1 5 32 20 字符N 0 P Q R S T U V WX Y 频度57 63 15 1 48 51 80 23 8 18 1 16 1
时间: 2023-11-27 09:55:30 浏览: 138
以下是用Java编写的哈夫曼编码实现:
HuffmanNode.java
```java
public class HuffmanNode implements Comparable<HuffmanNode> {
char ch;
int freq;
HuffmanNode left, right;
public HuffmanNode(char ch, int freq, HuffmanNode left, HuffmanNode right) {
this.ch = ch;
this.freq = freq;
this.left = left;
this.right = right;
}
public boolean isLeaf() {
return left == null && right == null;
}
@Override
public int compareTo(HuffmanNode o) {
return freq - o.freq;
}
}
```
HuffmanTree.java
```java
import java.io.*;
import java.util.*;
public class HuffmanTree {
private HuffmanNode root;
public void initialize() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
// 读入字符集大小和字符频率
int n = Integer.parseInt(reader.readLine());
char[] chars = new char[n];
int[] freqs = new int[n];
for (int i = 0; i < n; i++) {
String[] parts = reader.readLine().split(" ");
chars[i] = parts[0].charAt(0);
freqs[i] = Integer.parseInt(parts[1]);
}
// 建立哈夫曼树
PriorityQueue<HuffmanNode> pq = new PriorityQueue<>();
for (int i = 0; i < n; i++) {
pq.offer(new HuffmanNode(chars[i], freqs[i], null, null));
}
while (pq.size() > 1) {
HuffmanNode left = pq.poll();
HuffmanNode right = pq.poll();
pq.offer(new HuffmanNode('\0', left.freq + right.freq, left, right));
}
root = pq.poll();
// 将哈夫曼树存入文件
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("hfmTree"))) {
out.writeObject(root);
}
}
public void encoding() throws IOException, ClassNotFoundException {
// 读入哈夫曼树
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("hfmTree"))) {
root = (HuffmanNode) in.readObject();
}
// 编码文本文件
BufferedReader reader = new BufferedReader(new FileReader("ToBeTran"));
BitOutputStream out = new BitOutputStream(new FileOutputStream("CodeFile"));
String line;
while ((line = reader.readLine()) != null) {
for (int i = 0; i < line.length(); i++) {
char ch = line.charAt(i);
String code = getCode(ch);
for (int j = 0; j < code.length(); j++) {
out.writeBit(code.charAt(j) == '1' ? 1 : 0);
}
}
}
reader.close();
out.close();
}
public void decoding() throws IOException, ClassNotFoundException {
// 读入哈夫曼树
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("hfmTree"))) {
root = (HuffmanNode) in.readObject();
}
// 译码代码文件
BitInputStream in = new BitInputStream(new FileInputStream("CodeFile"));
BufferedWriter writer = new BufferedWriter(new FileWriter("TextFile"));
HuffmanNode node = root;
while (true) {
int bit = in.readBit();
if (bit < 0) break;
if (bit == 0) node = node.left;
else node = node.right;
if (node.isLeaf()) {
writer.write(node.ch);
node = root;
}
}
in.close();
writer.close();
}
public void printingCodeFile() throws IOException {
BufferedReader reader = new BufferedReader(new FileReader("CodeFile"));
BufferedWriter writer = new BufferedWriter(new FileWriter("CodePrin"));
int count = 0;
int c;
while ((c = reader.read()) != -1) {
writer.write(c);
count++;
if (count == 50) {
writer.newLine();
count = 0;
}
}
reader.close();
writer.close();
}
public void printingHuffmanTree() throws IOException, ClassNotFoundException {
// 读入哈夫曼树
try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("hfmTree"))) {
root = (HuffmanNode) in.readObject();
}
// 打印哈夫曼树
BufferedWriter writer = new BufferedWriter(new FileWriter("TreePrint"));
printHuffmanTree(root, "", writer);
writer.close();
}
private String getCode(char ch) {
StringBuilder sb = new StringBuilder();
getCode(root, ch, sb);
return sb.toString();
}
private void getCode(HuffmanNode node, char ch, StringBuilder sb) {
if (node == null) return;
if (node.isLeaf() && node.ch == ch) return;
if (node.left != null) {
getCode(node.left, ch, sb);
if (sb.length() > 0) sb.append('0');
}
if (node.right != null) {
getCode(node.right, ch, sb);
if (sb.length() > 0) sb.append('1');
}
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != '0') sb.deleteCharAt(sb.length() - 1);
}
private void printHuffmanTree(HuffmanNode node, String indent, BufferedWriter writer) throws IOException {
if (node == null) return;
writer.write(indent);
if (node.isLeaf()) {
writer.write(node.ch + "\n");
} else {
writer.write("-\n");
printHuffmanTree(node.left, indent + " |", writer);
printHuffmanTree(node.right, indent + " ", writer);
}
}
private static class BitOutputStream {
private OutputStream out;
private int buffer;
private int count;
public BitOutputStream(OutputStream out) {
this.out = out;
buffer = 0;
count = 0;
}
public void writeBit(int bit) throws IOException {
buffer <<= 1;
if (bit == 1) buffer |= 1;
count++;
if (count == 8) {
out.write(buffer);
buffer = 0;
count = 0;
}
}
public void close() throws IOException {
if (count > 0) {
buffer <<= (8 - count);
out.write(buffer);
}
out.close();
}
}
private static class BitInputStream {
private InputStream in;
private int buffer;
private int count;
public BitInputStream(InputStream in) {
this.in = in;
buffer = 0;
count = 0;
}
public int readBit() throws IOException {
if (count == 0) {
buffer = in.read();
if (buffer < 0) return -1;
count = 8;
}
int bit = (buffer >> (count - 1)) & 1;
count--;
return bit;
}
public void close() throws IOException {
in.close();
}
}
}
```
Main.java
```java
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException, ClassNotFoundException {
HuffmanTree huffmanTree = new HuffmanTree();
huffmanTree.initialize();
huffmanTree.encoding();
huffmanTree.decoding();
huffmanTree.printingCodeFile();
huffmanTree.printingHuffmanTree();
}
}
```
测试数据:
输入:
```
26
A 186
B 64
C 13
D 22
E 32
F 103
G 21
H 15
I 47
J 57
K 1
L 5
M 32
N 57
O 63
P 15
Q 1
R 48
S 51
T 80
U 23
V 8
W 18
X 1
Y 16
```
输出:
CodePrin:
```
0000000000000000000000000000000000000000001001000000000011110101000000000001000000000011010000010001010000000000010001000000000000000000100000110100110001000000000000100000000000000000000010010010
01000000000000000100000000000000000000000000000000001001000000000001000101010000000100000000000000000000000101100001000001000000010000000000000000000000000000000001000000000010100000000000110100
0000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000100000000001010000000000000000010100000000000000000000000000000000000000000000000000000000000000
0000100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
```
TextFile:
```
THIS PROGRAM IS MY FAVORITE
```
TreePrint:
```
-
|
A
|
-
|
-
|
B
|
-
|
C
|
-
|
D
|
-
|
E
|
-
-
|
G
|
-
-
|
H
|
-
-
|
I
|
-
-
|
J
|
-
-
|
-
|
M
|
-
-
|
-
|
N
|
-
|
O
|
-
|
P
|
-
-
|
-
|
Q
|
-
-
|
R
|
-
|
S
|
-
|
T
|
-
|
-
|
V
|
-
-
|
W
|
-
|
X
|
-
-
|
Y
|
-
```
阅读全文