标签:buffer 最小 col tostring 哈夫曼树 文字 相加 文件 pareto
实现时参考了博客
java创建哈夫曼树和实现哈夫曼编码和坤澎的博客——java实现哈夫曼编码,在读懂代码的同时,在一些地方加上了自己的备注
HuffmanNode
利用泛型实现结点,定义左子树,右子树,权值和编码。// 哈夫曼节点类
public class HuffmanNode<T> implements Comparable<HuffmanNode<T>> {
private T data; // 数据
private double weight; // 权重
private HuffmanNode<T> left;
private HuffmanNode<T> right;
String code; // 编码
public HuffmanNode(T data, double weight){
this.data = data;
this.weight = weight;
this.code = "";
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public HuffmanNode<T> getLeft() {
return left;
}
public void setLeft(HuffmanNode<T> left) {
this.left = left;
}
public HuffmanNode<T> getRight() {
return right;
}
public void setRight(HuffmanNode<T> right) {
this.right = right;
}
public String getCode(){
return code;
}
public void setCode(String str){
code = str;
}
@Override
public String toString(){
return null;
}
@Override
public int compareTo(HuffmanNode<T> other) {
if(other.getWeight() > this.getWeight()){
return 1;
}
if(other.getWeight() < this.getWeight()){
return -1;
}
return 0;
}
}
ReadTxt
类读取txt文件中的字母,用于将字母转化成哈夫曼编码。// 读取文件类
public class ReadTxt {
char[] chars = new char[]{'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s'
,'t','u','v','w','x','y','z',' '};
// int[] nu = new int[26];
int[] number = new int[]{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
public String txtString(File file){
StringBuilder result = new StringBuilder();
try{
BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
String s = null;
while((s = br.readLine())!=null){// 使用readLine方法,一次读一行
result.append(System.lineSeparator() + s);
num(s);
}
br.close();
}catch(Exception e){
e.printStackTrace();
}
return result.toString();
}
public void num(String string){
// 26个字母加一个空格
for(int i = 0;i<27;i++){
int temp = 0;
for(int j = 0;j<string.length();j++){
if(string.charAt(j) == chars[i]) {
temp++;
}
}
number[i] += temp;
}
}
public int[] getNumber(){
return number;
}
public char[] getChars(){
return chars;
}
}
HuffmanCoding
类将读取的字母转化成为哈夫曼编码,并且规定左子树为0,右子树为1public class HuffmanCoding<T> {
public HuffmanNode<T> createTree(List<HuffmanNode<T>> nodes) {
while (nodes.size() > 1) {
Collections.sort(nodes);
HuffmanNode<T> left = nodes.get(nodes.size() - 2);
left.setCode(0 + ""); // 左子树为否(0)
HuffmanNode<T> right = nodes.get(nodes.size() - 1);
right.setCode(1 + ""); // 右子树为是(1)
HuffmanNode<T> parent = new HuffmanNode<>(null, left.getWeight() + right.getWeight()); // 双亲结点的权值为左右孩子相加
parent.setLeft(left);
parent.setRight(right);
nodes.remove(left);
nodes.remove(right);
nodes.add(parent);
}
return nodes.get(0); // 返回根结点
}
// 广度优先遍历以赋值
public List<HuffmanNode<T>> BFS(HuffmanNode<T> root) {
List<HuffmanNode<T>> list = new ArrayList<>();
Queue<HuffmanNode<T>> queue = new ArrayDeque<>();
if (root != null) {
// 将元素入队列
queue.offer(root);
root.getLeft().setCode(root.getCode() + "0");
root.getRight().setCode(root.getCode() + "1");
}
// 转化为0和1
while (!queue.isEmpty()) {
list.add(queue.peek());
HuffmanNode<T> node = queue.poll(); // 获取头结点
if (node.getLeft() != null) {
node.getLeft().setCode(node.getCode() + "0"); // 左为0
}
if (node.getRight() != null) {
node.getRight().setCode(node.getCode() + "1"); // 右为1
}
if (node.getLeft() != null) {
queue.offer(node.getLeft());
}
if (node.getRight() != null) {
queue.offer(node.getRight());
}
}
return list;
}
}
Huffman
从input.txt
中读取信息,转化为哈夫曼编码后将哈夫曼编码放入output.txt
中后完成测试。public class Huffman {
public static void main(String[] args) throws IOException {
List<HuffmanNode<String>> list = new ArrayList<>();
List<HuffmanNode<String>> list2;
List<String> list3 = new ArrayList<>();
List<String> list4 = new ArrayList<>();
List<String> list5 = new ArrayList<>();
String temp2 = "",temp3 = "";
String result="";
double num2 = 0;
File file = new File("C:\\Users\\机械革命.000\\Desktop\\程序设计\\大二上\\哈夫曼\\input.txt");
ReadTxt read = new ReadTxt();
String temp = read.txtString(file);
System.out.println("读取的文件是:" + temp);
int[] num = read.getNumber(); // 存放出现次数的数组
char[] chars = read.getChars(); // 存放元素的数组
for(int i = 0;i<27;i++){
System.out.print(chars[i]+":"+num[i]+" ");
list.add(new HuffmanNode<>(chars[i]+"",num[i]));
}
Collections.sort(list); // 按照自然顺序排序
System.out.println();
HuffmanCoding huffmanTree = new HuffmanCoding();
HuffmanNode<String> root = huffmanTree.createTree(list);
list2 = huffmanTree.BFS(root);// 利用广度优先遍历遍历整棵树后赋值
for(int i = 0;i<list2.size();i++){
if(list2.get(i).getData()!=null) {
list3.add(list2.get(i).getData());
list4.add(list2.get(i).getCode());
}
}
for(int i = 0;i<list2.size();i++){
num2 += list2.get(i).getWeight();
}
Collections.sort(list3);
System.out.println("出现的概率中第一个代表空格。");
for(int i = 0;i<list3.size();i++){
System.out.print(list3.get(i) + "出现的概率为:" + list2.get(i).getWeight()/num2 + " \n");
}
System.out.println();
for(int i = 0;i<list4.size();i++){
System.out.print(list3.get(i)+"的编码为:"+list4.get(i)+" \n");
}
System.out.println();
for(int i = 0;i<temp.length();i++){
for(int j = 0;j<list3.size();j++){
if(temp.charAt(i) == list3.get(j).charAt(0)) {
result += list4.get(j);
}
}
}
for(int i = 0;i<result.length();i++){
list5.add(result.charAt(i)+"");
}
while (list5.size()>0){
temp2 = temp2+"" +list5.get(0);
list5.remove(0);
for(int i=0;i<list4.size();i++){
if (temp2.equals(list4.get(i))) {
temp3 = temp3+""+list3.get(i);
temp2 = "";
}
}
}
System.out.println();
System.out.println("编码前:" + temp);
System.out.println("编码后为:\n"+ result);
System.out.println("解码后:"+"\n"+temp3);
File file2 =new File("C:\\Users\\机械革命.000\\Desktop\\程序设计\\大二上\\哈夫曼\\output.txt");
Writer out =new FileWriter(file2);
out.write(result); // 将哈夫曼编码放入output.txt中
out.close();
}
}
Collections.sort
方法时不了解该方法,也不了解如何使用。该方法是一个排序方法,升序排序。
Queue.offer
方法不了解。172322 2018-2019-1 《程序设计与数据结构》哈夫曼编码测试报告
标签:buffer 最小 col tostring 哈夫曼树 文字 相加 文件 pareto
原文地址:https://www.cnblogs.com/zhangyeye233/p/10100120.html