用java写一个完整的系统具有以下功能: (11:初始化(lnitialization)。从终端读入宇符集大小口,以及口个字符和口个 权值,建立哈夫曼树,并将它存于文件hfimTree中。 (②E:编码(Encoding)。利用己建好的哈夫曼树(如不在内存,则从文件 hfinTree中读人),对文件ToBeTran中的正文进行编码,然后将结果存入文件 CodeFile T• (3)D:译码(Decoding)。利用己建好的哈夫曼树将文件CodeFile中的代码进 行译码,结果存入文件TextFile中。 (④P:打印代码文件(Print。将文件CodeFile以紧湊格式显示在终端上,每 行50个代码。同时将此字符形式的编码文件写入文件CodePrin中。 (5T:打印哈夫曼树(Treeprinting)。将已在内存中的哈夫曼树以直观的方式 (树或四入表形式)显示在终端上,同时将此字符形式的哈夫曼树写入文件 TreePrint中。
时间: 2023-06-26 22:09:29 浏览: 111
以下是一个 Java 实现的示例代码,实现了上述功能:
```java
import java.io.*;
import java.util.*;
class HuffmanTreeNode implements Comparable<HuffmanTreeNode> {
public char ch;
public int freq;
public HuffmanTreeNode left;
public HuffmanTreeNode right;
public HuffmanTreeNode(char ch, int freq) {
this.ch = ch;
this.freq = freq;
}
public HuffmanTreeNode(int freq, HuffmanTreeNode left, HuffmanTreeNode right) {
this.freq = freq;
this.left = left;
this.right = right;
}
public boolean isLeaf() {
return left == null && right == null;
}
public int compareTo(HuffmanTreeNode node) {
return freq - node.freq;
}
}
class HuffmanTree {
private HuffmanTreeNode root;
private Map<Character, String> codeTable;
public HuffmanTree(Map<Character, Integer> freqTable) {
PriorityQueue<HuffmanTreeNode> pq = new PriorityQueue<>();
for (char ch : freqTable.keySet()) {
pq.offer(new HuffmanTreeNode(ch, freqTable.get(ch)));
}
while (pq.size() > 1) {
HuffmanTreeNode left = pq.poll();
HuffmanTreeNode right = pq.poll();
pq.offer(new HuffmanTreeNode(left.freq + right.freq, left, right));
}
root = pq.poll();
buildCodeTable();
}
private void buildCodeTable() {
codeTable = new HashMap<>();
buildCodeTable(root, "");
}
private void buildCodeTable(HuffmanTreeNode node, String code) {
if (node.isLeaf()) {
codeTable.put(node.ch, code);
} else {
buildCodeTable(node.left, code + "0");
buildCodeTable(node.right, code + "1");
}
}
public void printTree(PrintStream out) {
printTree(out, root, "");
}
private void printTree(PrintStream out, HuffmanTreeNode node, String prefix) {
if (node == null) {
return;
}
out.println(prefix + (node.isLeaf() ? node.ch : "*"));
printTree(out, node.left, prefix + "| ");
printTree(out, node.right, prefix + "| ");
}
public void saveToFile(File file) throws IOException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(root);
oos.flush();
oos.close();
}
public static HuffmanTree loadFromFile(File file) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
HuffmanTreeNode root = (HuffmanTreeNode) ois.readObject();
ois.close();
HuffmanTree tree = new HuffmanTree(Collections.emptyMap());
tree.root = root;
tree.buildCodeTable();
return tree;
}
public String encode(String text) {
StringBuilder sb = new StringBuilder();
for (char ch : text.toCharArray()) {
sb.append(codeTable.get(ch));
}
return sb.toString();
}
public String decode(String code) {
StringBuilder sb = new StringBuilder();
HuffmanTreeNode node = root;
for (char bit : code.toCharArray()) {
if (bit == '0') {
node = node.left;
} else {
node = node.right;
}
if (node.isLeaf()) {
sb.append(node.ch);
node = root;
}
}
return sb.toString();
}
}
public class HuffmanCodingSystem {
private static final int LINE_WIDTH = 50;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter alphabet size: ");
int size = scanner.nextInt();
scanner.nextLine();
Map<Character, Integer> freqTable = new HashMap<>();
for (int i = 0; i < size; i++) {
System.out.printf("Enter character %d and its frequency: ", i + 1);
char ch = scanner.nextLine().charAt(0);
int freq = scanner.nextInt();
scanner.nextLine();
freqTable.put(ch, freq);
}
HuffmanTree tree = new HuffmanTree(freqTable);
try {
tree.saveToFile(new File("huffmanTree"));
} catch (IOException e) {
System.err.println("Error saving Huffman tree to file: " + e.getMessage());
return;
}
System.out.print("Enter command (E/D/P/T): ");
String command = scanner.nextLine();
if (command.equalsIgnoreCase("E")) {
System.out.print("Enter input file name: ");
String inputFileName = scanner.nextLine();
System.out.print("Enter output file name: ");
String outputFileName = scanner.nextLine();
String input = readFile(inputFileName);
String code = tree.encode(input);
writeFile(outputFileName, code);
System.out.println("Done!");
} else if (command.equalsIgnoreCase("D")) {
System.out.print("Enter input file name: ");
String inputFileName = scanner.nextLine();
System.out.print("Enter output file name: ");
String outputFileName = scanner.nextLine();
String code = readFile(inputFileName);
String text = tree.decode(code);
writeFile(outputFileName, text);
System.out.println("Done!");
} else if (command.equalsIgnoreCase("P")) {
System.out.print("Enter input file name: ");
String inputFileName = scanner.nextLine();
System.out.print("Enter output file name: ");
String outputFileName = scanner.nextLine();
String code = readFile(inputFileName);
printCode(code);
writeFile(outputFileName, code);
System.out.println("Done!");
} else if (command.equalsIgnoreCase("T")) {
tree.printTree(System.out);
try {
PrintWriter pw = new PrintWriter(new FileWriter("treePrint"));
tree.printTree(pw);
pw.close();
} catch (IOException e) {
System.err.println("Error writing Huffman tree print to file: " + e.getMessage());
}
} else {
System.err.println("Invalid command: " + command);
}
}
private static String readFile(String fileName) {
StringBuilder sb = new StringBuilder();
try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
System.err.println("Error reading file: " + e.getMessage());
}
return sb.toString();
}
private static void writeFile(String fileName, String content) {
try (PrintWriter pw = new PrintWriter(new FileWriter(fileName))) {
pw.print(content);
} catch (IOException e) {
System.err.println("Error writing file: " + e.getMessage());
}
}
private static void printCode(String code) {
int i = 0;
while (i < code.length()) {
int j = i + LINE_WIDTH;
if (j > code.length()) {
j = code.length();
}
System.out.println(code.substring(i, j));
i = j;
}
}
}
```
该程序通过命令行交互,支持以下命令:
- `E`:编码。输入一个输入文件名和一个输出文件名,在输入文件中读取文本并进行编码,将编码后的结果存入输出文件。
- `D`:译码。输入一个输入文件名和一个输出文件名,在输入文件中读取编码后的文本并进行译码,将译码后的结果存入输出文件。
- `P`:打印代码文件。输入一个输入文件名和一个输出文件名,在输入文件中读取编码后的文本并以紧凑格式显示在终端上,每行50个代码,并将此编码文件写入输出文件。
- `T`:打印哈夫曼树。将已在内存中的哈夫曼树以树或表格形式显示在终端上,并将此哈夫曼树写入文件中。
该程序通过 `HuffmanTree` 类实现哈夫曼树的建立、保存和加载,通过 `encode` 和 `decode` 方法实现编码和译码,通过 `printTree` 方法实现哈夫曼树的打印。
阅读全文