构建哈夫曼树压缩 java_huffman树实现的压缩算法,java

packagehuffman;import java.io.*;importjava.lang.reflect.Array;import java.util.*;public classTextZip {private static final String ID = "201692388";/*** This method generates the huffman tree for the text: "abracadabra!"

*

*@returnthe root of the huffman tree*/

public staticTreeNode abracadbraTree() {

TreeNode n0= new TreeNode(new CharFreq('!', 1));

TreeNode n1= new TreeNode(new CharFreq('c', 1));

TreeNode n2= new TreeNode(new CharFreq('\u0000', 2), n0, n1);

TreeNode n3= new TreeNode(new CharFreq('r', 2));

TreeNode n4= new TreeNode(new CharFreq('\u0000', 4), n3, n2);

TreeNode n5= new TreeNode(new CharFreq('d', 1));

TreeNode n6= new TreeNode(new CharFreq('b', 2));

TreeNode n7= new TreeNode(new CharFreq('\u0000', 3), n5, n6);

TreeNode n8= new TreeNode(new CharFreq('\u0000', 7), n7, n4);

TreeNode n9= new TreeNode(new CharFreq('a', 5));

TreeNode n10= new TreeNode(new CharFreq('\u0000', 12), n9, n8);returnn10;

}/*** This method decompresses a huffman compressed text file. The compressed

* file must be read one bit at a time using the supplied BitReader, and

* then by traversing the supplied huffman tree, each sequence of compressed

* bits should be converted to their corresponding characters. The

* decompressed characters should be written to the FileWriter

*

*@parambr the BitReader which reads one bit at a time from the

* compressed file

* huffman the huffman tree that was used for compression, and

* hence should be used for decompression

* fw a FileWriter for storing the decompressed text file*/

public static void decompress(BitReader br, TreeNode huffman, FileWriter fw) throwsException {//IMPLEMENT THIS METHOD

TreeNode scaner =huffman;while(br.hasNext()){for(;!scaner.isLeaf() &&br.hasNext();){if(br.next())

scaner=scaner.getRight();elsescaner=scaner.getLeft();

}

CharFreq item=(CharFreq)(scaner.getItem());

fw.write(item.getChar());

scaner=huffman;

}

}/*** This method traverses the supplied huffman tree and prints out the

* codes associated with each character

*

*@paramt the root of the huffman tree to be traversed

* code a String used to build the code for each character as

* the tree is traversed recursively*/

static Map table = new Hashtable<>();public static voidtraverse(TreeNode t, String code) {//IMPLEMENT THIS METHOD

if(!t.isLeaf()){

traverse(t.getLeft(), code+ '0');

traverse(t.getRight(),code+ '1');

}else{

CharFreq item=(CharFreq) (t.getItem());

table.put(item.getChar(), code);

System.out.println(item.getChar()+": "+code);

}

}//public static Map traverse(TreeNode t) {//

//Map table = new Hashtable<>();//

// //IMPLEMENT THIS METHOD//if(!t.isLeaf()){//traverse(t.getLeft());//traverse(t.getRight());//}//else {//CharFreq item = (CharFreq) (t.getItem());//System.out.println(item.getChar()+": " + "code");//}//}

/*** This method removes the TreeNode, from an ArrayList of TreeNodes, which

* contains the smallest item. The items stored in each TreeNode must

* implement the Comparable interface.

* The ArrayList must contain at least one element.

*

*@parama an ArrayList containing TreeNode objects

*

*@returnthe TreeNode in the ArrayList which contains the smallest item.

* This TreeNode is removed from the ArrayList.*/

public staticTreeNode removeMin(ArrayList a) {int minIndex = 0;for (int i = 0; i < a.size(); i++) {

TreeNode ti=(TreeNode)(a.get(i));

TreeNode tmin=(TreeNode)(a.get(minIndex));if (((Comparable)(ti.getItem())).compareTo(tmin.getItem()) < 0)

minIndex=i;

}

TreeNode n=(TreeNode)a.remove(minIndex);returnn;

}/*** This method counts the frequencies of each character in the supplied

* FileReader, and produces an output text file which lists (on each line)

* each character followed by the frequency count of that character. This

* method also returns an ArrayList which contains TreeNodes. The item stored

* in each TreeNode in the returned ArrayList is a CharFreq object, which

* stores a character and its corresponding frequency

*

*@paramfr the FileReader for which the character frequencies are being

* counted

* pw the PrintWriter which is used to produce the output text file

* listing the character frequencies

*

*@returnthe ArrayList containing TreeNodes. The item stored in each

* TreeNode is a CharFreq object.*/

public static ArrayList countFrequencies(FileReader fr, PrintWriter pw) throwsException {//IMPLEMENT THIS METHOD

intc;

ArrayList list = new ArrayList<>();while ((c = fr.read()) != -1) {if(list.isEmpty()) {

list.add(new TreeNode(new CharFreq((char) c, 1)));continue;

}inti;for( i=0; i

TreeNode temp=list.get(i);

CharFreq item=(CharFreq) (temp.getItem());if((char)c ==item.getChar())

list.set(i,new TreeNode(new CharFreq((char)c, item.getFreq() + 1)));

}if(i >=list.size())

list.add(new TreeNode(new CharFreq((char)c, 1)));

}for(int i = 0; i < list.size(); i++){

CharFreq temp=(CharFreq)(list.get(i).getItem());

pw.print(temp);

}returnlist;

}/*** This method builds a huffman tree from the supplied ArrayList of TreeNodes.

* Initially, the items in each TreeNode in the ArrayList store a CharFreq object.

* As the tree is built, the smallest two items in the ArrayList are removed,

* merged to form a tree with a CharFreq object storing the sum of the frequencies

* as the root, and the two original CharFreq objects as the children. The right

* child must be the second of the two elements removed from the ArrayList (where

* the ArrayList is scanned from left to right when the minimum element is found).

* When the ArrayList contains just one element, this will be the root of the

* completed huffman tree.

*

*@paramtrees the ArrayList containing the TreeNodes used in the algorithm

* for generating the huffman tree

*

*@returnthe TreeNode referring to the root of the completed huffman tree*/

public static TreeNode buildTree(ArrayList trees) throwsIOException {//IMPLEMENT THIS METHOD

while(trees.size() > 1){

TreeNode rleft=removeMin(trees);

TreeNode rright=removeMin(trees);

CharFreq item= new CharFreq('\u0000',((CharFreq)rleft.getItem()).getFreq() +((CharFreq)rright.getItem()).getFreq() );

TreeNode root= newTreeNode( item, rleft, rright);

trees.add( root );

}return (TreeNode)trees.get(0);

}/*** This method compresses a text file using huffman encoding. Initially, the

* supplied huffman tree is traversed to generate a lookup table of codes for

* each character. The text file is then read one character at a time, and

* each character is encoded by using the lookup table. The encoded bits for

* each character are written one at a time to the specified BitWriter.

*

*@paramfr the FileReader which contains the text file to be encoded

* huffman the huffman tree that was used for compression, and

* hence should be used for decompression

* bw the BitWriter used to write the compressed bits to file*/

public static void compress(FileReader fr, TreeNode huffman, BitWriter bw) throwsException {//IMPLEMENT THIS METHOD

traverse(huffman,"");intc;while((c = fr.read()) != -1){char c1 = (char) c;

String code=table.get(c);char[] arrayCodes =code.toCharArray();for(int i = 0; i < arrayCodes.length; i++){if(arrayCodes[i] == '0')

bw.writeBit(false);if(arrayCodes[i] == '1')

bw.writeBit(true);

}

}

}/*** This method reads a frequency file (such as those generated by the

* countFrequencies() method) and initialises an ArrayList of TreeNodes

* where the item of each TreeNode is a CharFreq object storing a character

* from the frequency file and its corresponding frequency. This method provides

* the same functionality as the countFrequencies() method, but takes in a

* frequency file as parameter rather than a text file.

*

*@paraminputFreqFile the frequency file which stores characters and their

* frequency (one character per line)

*

*@returnthe ArrayList containing TreeNodes. The item stored in each

* TreeNode is a CharFreq object.*/

public static ArrayList readFrequencies(String inputFreqFile) throwsException {//IMPLEMENT THIS METHOD

FileInputStream fis = newFileInputStream(inputFreqFile);

InputStreamReader isr= new InputStreamReader(fis,"utf-8");

BufferedReader br= newBufferedReader(isr);

ArrayList list = new ArrayList<>();

String s;while((s = br.readLine()) != null){

String[] ss= s.split(" ");

TreeNode t= new TreeNode(new CharFreq(ss[0].charAt(0), Integer.parseInt(ss[1])));

list.add(t);

}returnlist;

}/*This TextZip application should support the following command line flags:

QUESTION 2 PART 1

=================

-a : this uses a default prefix code tree and its compressed

file, "a.txz", and decompresses the file, storing the output

in the text file, "a.txt". It should also print out the size

of the compressed file (in bytes), the size of the decompressed

file (in bytes) and the compression ratio

QUESTION 2 PART 2

=================

-f : given a text file (args[1]) and the name of an output frequency file

(args[2]) this should count the character frequencies in the text file

and store these in the frequency file (with one character and its

frequency per line). It should then build the huffman tree based on

the character frequencies, and then print out the prefix code for each

character

QUESTION 2 PART 3

=================

-c : given a text file (args[1]) and the name of an output frequency file

(args[2]) and the name of the output compressed file (args[3]), this

should compress file

QUESTION 2 PART 4

=================

-d : given a compressed file (args[1]) and its corresponding frequency file

(args[2]) and the name of the output decompressed text file (args[3]),

this should decompress the file*/

public static void main(String[] args) throwsException {if (args[0].equals("-a")) {

BitReader br= new BitReader("a.txz");

FileWriter fw= new FileWriter("a.txt");//Get the default prefix code tree

TreeNode tn =abracadbraTree();//Decompress the default file "a.txz"

decompress(br, tn, fw);//Close the ouput file

fw.close();//Output the compression ratio//Write your own implementation here.

}else if (args[0].equals("-f")) {

FileReader fr= new FileReader(args[1]);

PrintWriter pw= new PrintWriter(new FileWriter(args[2]));//Calculate the frequencies

ArrayList trees =countFrequencies(fr, pw);//Close the files

fr.close();

pw.close();//Build the huffman tree

TreeNode n =buildTree(trees);//Display the codes

traverse(n, "");

}else if (args[0].equals("-c")) {

FileReader fr= new FileReader(args[1]);

PrintWriter pw= new PrintWriter(new FileWriter(args[2]));

ArrayList trees=countFrequencies(fr, pw);

fr.close();

pw.close();

TreeNode n=buildTree(trees);//IMPLEMENT NEXT//Finish the compress function here//then output the compression ratio//Write your own implementation here.

}else if (args[0].equals("-d")) {

ArrayList a= readFrequencies(args[2]);

TreeNode tn=buildTree(a);

BitReader br= new BitReader(args[1]);

FileWriter fw= new FileWriter(args[3]);

decompress(br, tn, fw);

fw.close();//Output the compression ratio//Write your own implementation here.

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值