Huffman
- 导入
import java.io.*;
import java.util.Scanner;
- huffman类的描述
/**
* 把想要翻译的英文文本,自己,写入text.txt文件中
* 至少2个字符
* 程序会自动计算每个字符的权值,构造赫夫曼树,生成每个字符的赫夫曼编码
* @author 己千之
*/
- 类的成员变量
/**
* 叶子节点个数
*/
int n;
/**
* 总节点个数
*/
int m;
/**
* 每次权值最小的两个
*/
int s1, s2;
/**
* text.txt文件里的内容
*/
String textString;
/**
* code.txt文件里的内容
*/
String codeString;
- 内部类:作节点
/**
* 内部类
* 赫夫曼树的节点的数据结构
* @author 己千之
*/
class HuffmanTreeNode {
char data;
int weight;
HuffmanTreeNode parent, lchild, rchild;
HuffmanTreeNode() {
data = '0';
weight = 0;
parent = lchild = rchild = null;
}
HuffmanTreeNode(char a, int b, HuffmanTreeNode c, HuffmanTreeNode d, HuffmanTreeNode e) {
data = a;
weight = b;
parent = c;
lchild = d;
rchild = e;
}
}
/**
* 赫夫曼编码的数据结构
* @author 己千之
*/
class HuffmanCodeNode {
char data;
String code;
HuffmanCodeNode() {
data = '0';
code = "0";
}
HuffmanCodeNode(char a, String b) {
data = a;
code = b;
}
public String toString() {
return "< "+data+" "+code+" >";
}
}
/**
* 叶子节点的数据结构
* @author 己千之
*/
class LeafNode {
char data;
int weight;
LeafNode() {
data = '0';
weight = 0;
}
LeafNode(char a, int b) {
data = a;
weight = b;
}
public String toString() {
return "< "+data+" "+weight+" >";
}
}
- 初始
LeafNode[] w = new LeafNode[128];
HuffmanTreeNode[] HTNode = new HuffmanTreeNode[255];
HuffmanCodeNode[] HCNode = new HuffmanCodeNode[255];
- 基本方法
public void setN(int num) {
n = num;
}
public void setM(int num) {
m = num;
}
public void setS1(int num) {
s1 = num;
}
public void setS2(int num) {
s2 = num;
}
- 注意1:writeToText()
/**
* 假如你不想输入,你可以在Main()方法中把writeToText(filename1)去掉
* 可以直接把你想翻译的文本输进text.txt文本就行
*/
- 注意2:Main()
/**
* 对赫夫曼方法的集成
* 因为我试了,少了任何一个方法没有调用,程序就会报错。
*/
- 写入文件
/**
* 假如你不想输,你可以在Main()方法中把writeToText(filename1)去掉
* 可以直接把你想翻译的文本输进text.txt文本就行
* @param filename
*/
public void writeToText(String filename) {
System.out.println("请输入文本:");
Scanner sc = new Scanner(System.in);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(filename));
out.write(sc.nextLine());
out.close();
sc.close();
System.out.println("操作成功!");
}catch(IOException e) {
e.printStackTrace(); // 显示错误信息,和位置
}
}
- 统计字符次数
/**
* 读取text.txt文件内容
* 计算每个字符出现的次数
* @param filename
*/
public void readCount(String filename) {
BufferedReader reader = null;
StringBuffer strBuffer = null;
try {
reader = new BufferedReader(new FileReader(filename));
strBuffer = new StringBuffer();
String lines;
while((lines=reader.readLine()) != null) {
strBuffer.append(lines);
}
} catch (IOException e) {
// 以StringBuffer为操作
e.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} // end try...
String text = new String(strBuffer);
System.out.println("一、读取文本为:");
System.out.println(text);
textString = text;
// 去重
String newText = "";
for(int i=0; i<text.length(); i++) {
// indexof():对大小写敏感,对没出现的字符返回-1
if(newText.indexOf(text.charAt(i)) == -1) {
newText += text.charAt(i);
}
}
// 返回叶子个数
setN(newText.length());
setM(2*n-1);
// 统计字符次数
System.out.println("二、统计结果为 ( < 字符 权值 > ) :");
for(int i=0; i<newText.length(); i++) {
int count = 0;
for(int j=0; j<text.length(); j++) {
if(newText.charAt(i) == text.charAt(j)) {
count++;
}
}
LeafNode LNode = new LeafNode(newText.charAt(i), count);
System.out.println(LNode.toString());
w[i+1] = LNode;
}
System.out.println("(共"+n+"种字符)");
} // end ReadCount
- select
/**
* 构造赫夫曼树用到的函数,选取权值最小的两个节点的位置
* @param HT
* @param n
*/
public void selectMin(HuffmanTreeNode[] HT, int n) {
int i;
for(i=1; i<=n; i++) {
if(HT[i].parent == null) {
setS1(i);
break;
}
}
for(i=1; i<=n; i++) {
if(HT[i].parent==null && HT[s1].weight>HT[i].weight) {
setS1(i);
}
}
for(i=1; i<=n; i++) {
if(HT[i].parent==null && i!=s1) {
setS2(i);
break;
}
}
for(i=1; i<=n; i++) {
if(HT[i].parent==null && HT[s2].weight>HT[i].weight && i!=s1) {
setS2(i);
}
}
} // end select
- 构建赫夫曼树
/**
* 构建赫夫曼树
*/
public void creatHuffmanTree() {
int i;
// init
for(i=1; i<=n; i++) {
HTNode[i] = new HuffmanTreeNode(w[i].data, w[i].weight, null, null, null);
}
for(i=n+1; i<=m; i++) {
HTNode[i] = new HuffmanTreeNode();
}
// 建叶子以上的节点,链接
for(i=n+1; i<=m; i++) {
selectMin(HTNode, i-1);
HTNode[s1].parent = HTNode[i]; HTNode[s2].parent = HTNode[i];
HTNode[i].lchild = HTNode[s1]; HTNode[i].rchild = HTNode[s2];
HTNode[i].weight = HTNode[s1].weight+HTNode[s2].weight;
}
} // end creatHuffmanTree
- 写入code文件
/**
* 把text转化成赫夫曼报文 存储到 code文件
* @param filename2
*/
public void writeCodeToFile(String filename2) {
String tempString = "";
for(int i=0; i<textString.length(); i++) {
char ch = textString.charAt(i);
for(int j=1; j<=n; j++) {
if(ch == HCNode[j].data) {
tempString += HCNode[j].code;
}
}
}
System.out.println("四、赫夫曼报文:");
System.out.println(tempString);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(filename2));
out.write(tempString);
out.close();
System.out.println("五、把赫夫曼报文储存到code文件,操作成功!");
}catch(IOException e) {
e.printStackTrace(); // 显示错误信息,和位置
}
codeString = tempString;
}
- 编码
/**
* 编码
*/
public void encoding() {
int i;
// encoding
for(i=1; i<=n; i++) {
// init
HCNode[i] = new HuffmanCodeNode();
// data
HCNode[i].data = HTNode[i].data;
// code
HuffmanTreeNode tempNode;
tempNode = HTNode[i];
String tempString = "";
while(tempNode.parent != null) {
if(tempNode == tempNode.parent.lchild) tempString = "0" + tempString;
else tempString = "1" + tempString;
tempNode = tempNode.parent;
}
HCNode[i].code = tempString;
}
// 打印
System.out.println("三、每个字符对应的编码为:( < 字符 赫夫曼编码 > )");
for(i=1; i<=n; i++) {
System.out.println(HCNode[i].toString());
}
} // end encoding
- 译码
/**
* 译码
*/
public void decoding() {
int i;
HuffmanTreeNode tempNode;
String tempString = "";
tempNode = HTNode[2*n-1];
for(i=0; i<codeString.length(); i++) {
if(codeString.charAt(i) == '0') {
tempNode = tempNode.lchild;
}
else {
tempNode = tempNode.rchild;
}
if(tempNode.lchild == null) {
tempString += tempNode.data;
tempNode = HTNode[2*n-1];
}
}
System.out.println("六、根据code文件的码,译文:");
System.out.println(tempString);
} // end decoding
- 方法集成
/**
* 对赫夫曼方法的集成
* 因为我试了,少了任何一个方法没有调用,程序就会报错。
* @param filename1
* @param filename2
*/
public void Main(String filename1, String filename2) {
writeToText(filename1);
readCount(filename1);
creatHuffmanTree();
encoding();
writeCodeToFile(filename2);
decoding();
}
- 测试类
public class Test_Huffman {
public static void main(String[] args) {
final String filepath1 = "D:\\Java Space\\Java 0~100\\src\\Huffman\\text.txt";
final String filepath2 = "D:\\Java Space\\Java 0~100\\src\\Huffman\\code.txt";
Huffman huffman = new Huffman();
huffman.Main(filepath1, filepath2);
}
}
- 效果图

- 源码:
拷贝即用,只需要在D盘下面新建:
text.txt和code.txt
import java.io.*;
import java.util.Scanner;
/**
* 把想要翻译的英文文本,自己,写入text.txt文件中
* 至少2个字符
* 程序会自动计算每个字符的权值,构造赫夫曼树,生成每个字符的赫夫曼编码
* @author 己千之
*/
class Huffman {
/**
* 叶子节点个数
*/
int n;
/**
* 总节点个数
*/
int m;
/**
* 每次权值最小的两个
*/
int s1, s2;
/**
* text.txt文件里的内容
*/
String textString;
/**
* code.txt文件里的内容
*/
String codeString;
/**
* 内部类
* 赫夫曼树的节点的数据结构
* @author 己千之
*/
class HuffmanTreeNode {
char data;
int weight;
HuffmanTreeNode parent, lchild, rchild;
HuffmanTreeNode() {
data = '0';
weight = 0;
parent = lchild = rchild = null;
}
HuffmanTreeNode(char a, int b, HuffmanTreeNode c, HuffmanTreeNode d, HuffmanTreeNode e) {
data = a;
weight = b;
parent = c;
lchild = d;
rchild = e;
}
}
/**
* 赫夫曼编码的数据结构
* @author 己千之
*/
class HuffmanCodeNode {
char data;
String code;
HuffmanCodeNode() {
data = '0';
code = "0";
}
HuffmanCodeNode(char a, String b) {
data = a;
code = b;
}
public String toString() {
return "< "+data+" "+code+" >";
}
}
/**
* 叶子节点的数据结构
* @author 己千之
*/
class LeafNode {
char data;
int weight;
LeafNode() {
data = '0';
weight = 0;
}
LeafNode(char a, int b) {
data = a;
weight = b;
}
public String toString() {
return "< "+data+" "+weight+" >";
}
}
LeafNode[] w = new LeafNode[128];
HuffmanTreeNode[] HTNode = new HuffmanTreeNode[255];
HuffmanCodeNode[] HCNode = new HuffmanCodeNode[255];
public void setN(int num) {
n = num;
}
public void setM(int num) {
m = num;
}
public void setS1(int num) {
s1 = num;
}
public void setS2(int num) {
s2 = num;
}
/**
* 假如你不想输,你可以在Main()方法中把writeToText(filename1)去掉
* 可以直接把你想翻译的文本输进text.txt文本就行
* @param filename
*/
public void writeToText(String filename) {
System.out.println("请输入文本:");
Scanner sc = new Scanner(System.in);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(filename));
out.write(sc.nextLine());
out.close();
sc.close();
System.out.println("操作成功!");
}catch(IOException e) {
e.printStackTrace(); // 显示错误信息,和位置
}
}
/**
* 读取text.txt文件内容
* 计算每个字符出现的次数
* @param filename
*/
public void readCount(String filename) {
BufferedReader reader = null;
StringBuffer strBuffer = null;
try {
reader = new BufferedReader(new FileReader(filename));
strBuffer = new StringBuffer();
String lines;
while((lines=reader.readLine()) != null) {
strBuffer.append(lines);
}
} catch (IOException e) {
// 以StringBuffer为操作
e.printStackTrace();
} finally {
if(reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} // end try...
String text = new String(strBuffer);
System.out.println("一、读取文本为:");
System.out.println(text);
textString = text;
// 去重
String newText = "";
for(int i=0; i<text.length(); i++) {
// indexof():对大小写敏感,对没出现的字符返回-1
if(newText.indexOf(text.charAt(i)) == -1) {
newText += text.charAt(i);
}
}
// 返回叶子个数
setN(newText.length());
setM(2*n-1);
// 统计字符次数
System.out.println("二、统计结果为 ( < 字符 权值 > ) :");
for(int i=0; i<newText.length(); i++) {
int count = 0;
for(int j=0; j<text.length(); j++) {
if(newText.charAt(i) == text.charAt(j)) {
count++;
}
}
LeafNode LNode = new LeafNode(newText.charAt(i), count);
System.out.println(LNode.toString());
w[i+1] = LNode;
}
System.out.println("(共"+n+"种字符)");
} // end ReadCount
/**
* 构造赫夫曼树用到的函数,选取权值最小的两个节点的位置
* @param HT
* @param n
*/
public void selectMin(HuffmanTreeNode[] HT, int n) {
int i;
for(i=1; i<=n; i++) {
if(HT[i].parent == null) {
setS1(i);
break;
}
}
for(i=1; i<=n; i++) {
if(HT[i].parent==null && HT[s1].weight>HT[i].weight) {
setS1(i);
}
}
for(i=1; i<=n; i++) {
if(HT[i].parent==null && i!=s1) {
setS2(i);
break;
}
}
for(i=1; i<=n; i++) {
if(HT[i].parent==null && HT[s2].weight>HT[i].weight && i!=s1) {
setS2(i);
}
}
} // end select
/**
* 构建赫夫曼树
*/
public void creatHuffmanTree() {
int i;
// init
for(i=1; i<=n; i++) {
HTNode[i] = new HuffmanTreeNode(w[i].data, w[i].weight, null, null, null);
}
for(i=n+1; i<=m; i++) {
HTNode[i] = new HuffmanTreeNode();
}
// 建叶子以上的节点,链接
for(i=n+1; i<=m; i++) {
selectMin(HTNode, i-1);
HTNode[s1].parent = HTNode[i]; HTNode[s2].parent = HTNode[i];
HTNode[i].lchild = HTNode[s1]; HTNode[i].rchild = HTNode[s2];
HTNode[i].weight = HTNode[s1].weight+HTNode[s2].weight;
}
} // end creatHuffmanTree
/**
* 把text转化成赫夫曼报文 存储到 code文件
* @param filename2
*/
public void writeCodeToFile(String filename2) {
String tempString = "";
for(int i=0; i<textString.length(); i++) {
char ch = textString.charAt(i);
for(int j=1; j<=n; j++) {
if(ch == HCNode[j].data) {
tempString += HCNode[j].code;
}
}
}
System.out.println("四、赫夫曼报文:");
System.out.println(tempString);
try {
BufferedWriter out = new BufferedWriter(new FileWriter(filename2));
out.write(tempString);
out.close();
System.out.println("五、把赫夫曼报文储存到code文件,操作成功!");
}catch(IOException e) {
e.printStackTrace(); // 显示错误信息,和位置
}
codeString = tempString;
}
/**
* 编码
*/
public void encoding() {
int i;
// encoding
for(i=1; i<=n; i++) {
// init
HCNode[i] = new HuffmanCodeNode();
// data
HCNode[i].data = HTNode[i].data;
// code
HuffmanTreeNode tempNode;
tempNode = HTNode[i];
String tempString = "";
while(tempNode.parent != null) {
if(tempNode == tempNode.parent.lchild) tempString = "0" + tempString;
else tempString = "1" + tempString;
tempNode = tempNode.parent;
}
HCNode[i].code = tempString;
}
// 打印
System.out.println("三、每个字符对应的编码为:( < 字符 赫夫曼编码 > )");
for(i=1; i<=n; i++) {
System.out.println(HCNode[i].toString());
}
} // end encoding
/**
* 译码
*/
public void decoding() {
int i;
HuffmanTreeNode tempNode;
String tempString = "";
tempNode = HTNode[2*n-1];
for(i=0; i<codeString.length(); i++) {
if(codeString.charAt(i) == '0') {
tempNode = tempNode.lchild;
}
else {
tempNode = tempNode.rchild;
}
if(tempNode.lchild == null) {
tempString += tempNode.data;
tempNode = HTNode[2*n-1];
}
}
System.out.println("六、根据code文件的码,译文:");
System.out.println(tempString);
} // end decoding
/**
* 对赫夫曼方法的集成
* 因为我试了,少了任何一个方法没有调用,程序就会报错。
* @param filename1
* @param filename2
*/
public void Main(String filename1, String filename2) {
writeToText(filename1);
readCount(filename1);
creatHuffmanTree();
encoding();
writeCodeToFile(filename2);
decoding();
}
} // end huffman
public class Main {
public static void main(String[] args) {
final String filepath1 = "D:\\text.txt";
final String filepath2 = "D:\\code.txt";
Huffman huffman = new Huffman();
huffman.Main(filepath1, filepath2);
}
}
628

被折叠的 条评论
为什么被折叠?



