Advertisement
Guest User

Untitled

a guest
Nov 13th, 2015
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.88 KB | None | 0 0
  1. /* Student information for assignment:
  2. *
  3. * On our honor, Jonathan Madden and Khiem Tang, this programming assignment is our own work
  4. * and we have not provided this code to any other student.
  5. *
  6. * Number of slip days used: 1
  7. *
  8. * Student 1: Jonathan Madden
  9. * UTEID: jm76685
  10. * email address: johnmadden4477@yahoo.com
  11. * Grader name: Donghyuk
  12. * Section number: 51740
  13. *
  14. * Student 2: Khiem Tang
  15. * UTEID: klt2399
  16. * email address: tang.khiem@yahoo.com
  17. * Grader name: Donghyuk
  18. * Section number: 51740
  19. */
  20.  
  21. import java.io.IOException;
  22. import java.util.HashMap;
  23.  
  24. public class HuffmanTree {
  25. // Instance variables
  26. private TreeNode root;
  27. private HashMap<Integer, String> map;
  28. private int original;
  29. private int size;
  30. private int[] counts;
  31.  
  32. // HuffMan tree constructor to create initial priorityQueue and tree from queue
  33. public HuffmanTree(BitInputStream bits) throws IOException {
  34. // Defines counts int array to create frequencies
  35. counts = letterCount(bits);
  36. // Creates priority queue from frequency array
  37. PriorityQueue<TreeNode> queue = createQueue(counts);
  38. size = queue.size() * 10;
  39. // Creates tree from queue
  40. createTree(queue);
  41. map = new HashMap<Integer, String>();
  42. root = queue.front();
  43. // Creates map of integer/string based on queue root
  44. createMap(map, root, "");
  45. }
  46.  
  47. // HuffMan tree constructor for decompression:
  48. // Creates tree for use in making the standard count format tree for decompressing
  49. public HuffmanTree(int[] otherCounts) {
  50. this.counts = otherCounts;
  51. // Creates queue based on counts frequency array
  52. PriorityQueue<TreeNode> queue = createQueue(counts);
  53. // Creates tree based on the mapped priority queue
  54. size = queue.size();
  55. createTree(queue);
  56. map = new HashMap<Integer, String>();
  57. root = queue.front();
  58. // Creates map of integer/string based on queue root
  59. createMap(map, root, "");
  60. }
  61.  
  62. // HuffMan tree constructor for decompression:
  63. // Creates tree for use in making the standard tree format tree for decompressing
  64. public HuffmanTree(int tgtSize, BitInputStream bits) throws IOException {
  65. // Size condition with tgtSize, passed in from decompress call
  66. if (tgtSize>0) {
  67. size=tgtSize;
  68. // Reads the next bit
  69. int bit = bits.readBits(1);
  70. // Sets root to new node, initiate recursive method
  71. root = new TreeNode(bit, getChild(bits), getChild(bits));
  72. }
  73. }
  74.  
  75. // Helper method getChild to create node / leaf and place in data
  76. private TreeNode getChild(BitInputStream bits)
  77. throws IOException {
  78. // Defines bit as the next bit
  79. int bit = bits.readBits(1);
  80. TreeNode result;
  81. // If node is found, make node and continue recursive call
  82. if (bit == 0) {
  83. result = new TreeNode(bit, getChild(bits), getChild(bits));
  84. // If leaf is found
  85. } else {
  86. // Create new TreeNode with value of next 9 bits
  87. int value = bits.readBits(1 + IHuffConstants.BITS_PER_WORD);
  88. result = new TreeNode(value, 1);
  89. }
  90. return result;
  91. }
  92.  
  93. // getMap method to return hashMap
  94. public HashMap<Integer, String> getMap() {
  95. return map;
  96. }
  97.  
  98. // getRoot method to return root
  99. public TreeNode getRoot() {
  100. return root;
  101. }
  102.  
  103. // getOriginal method to obtain original file size
  104. public int getOriginal() {
  105. return original;
  106. }
  107.  
  108. // getSize method to return size
  109. public int getSize() {
  110. return size;
  111. }
  112.  
  113. // getCounts method to return frequency array
  114. public int[] getCounts() {
  115. return counts;
  116. }
  117.  
  118. // getSaved helper method to calculate compressed file size
  119. public int getSaved(int headerFormat) {
  120. // Defines letters as the frequency array
  121. int[] letters = getCounts();
  122. // Define codes as map of tree bits
  123. HashMap<Integer, String> codes = getMap();
  124. int afterCompress = 0;
  125. // Increment afterCompress variable with header and magic number
  126. afterCompress += IHuffConstants.BITS_PER_INT * 2;
  127. for (int x : codes.keySet()) {
  128. // Increments codes, including psuedo_eof
  129. afterCompress += codes.get(x).length() * letters[x];
  130. }
  131. // Incrementing for standard tree format
  132. if (headerFormat == IHuffConstants.STORE_TREE) {
  133. afterCompress += IHuffConstants.BITS_PER_INT; // size
  134. afterCompress += treeBits(getRoot());
  135. // Incrementing for standard count format
  136. } else if (headerFormat == IHuffConstants.STORE_COUNTS) {
  137. for (int k = 0; k < IHuffConstants.ALPH_SIZE; k++) {
  138. afterCompress += IHuffConstants.BITS_PER_INT;
  139. }
  140. }
  141. return getOriginal() - afterCompress;
  142. }
  143.  
  144. // treeBits helper method to return int bit of node
  145. private int treeBits(TreeNode node) {
  146. if (node != null) {
  147. // If node is a leaf, return corresponding bits
  148. if (node.isLeaf()) {
  149. return 2 + IHuffConstants.BITS_PER_WORD;
  150. } else {
  151. // Else, continue traversing tree
  152. return 1 + treeBits(node.getLeft()) + treeBits(node.getRight());
  153. }
  154. }
  155. return 0;
  156. }
  157.  
  158. // letterCount method for tallying letters
  159. private int[] letterCount(BitInputStream bits) throws IOException {
  160. // Define letter array with all possible character size
  161. int[] letters = new int[257];
  162. int inbits;
  163. // Read in bits until not possible, and tally letters
  164. while ((inbits = bits.readBits(IHuffConstants.BITS_PER_WORD)) != -1) {
  165. letters[inbits]++;
  166. // Increment original size variable
  167. original += 8;
  168. }
  169. // Increment PSUEDO_EOF index
  170. letters[IHuffConstants.PSEUDO_EOF]++;
  171. return letters;
  172. }
  173.  
  174. // createQueue method to create a new priority queue
  175. private PriorityQueue<TreeNode> createQueue(int[] letters) {
  176. PriorityQueue<TreeNode> counts = new PriorityQueue<TreeNode>();
  177. // runs through frequency array
  178. for (int x = 0; x < letters.length; x++) {
  179. if (letters[x] != 0) {
  180. // Enqueues when there is a visible character
  181. counts.enqueue(new TreeNode(x, letters[x]));
  182. }
  183. }
  184. return counts;
  185. }
  186.  
  187. // createTree method to create tree from priority queue
  188. private void createTree(PriorityQueue<TreeNode> counts) {
  189. while (counts.size() > 1) {
  190. // While size > 1 of priorityQueue, dequeue twice
  191. TreeNode temp1 = counts.dequeue();
  192. TreeNode temp2 = counts.dequeue();
  193. // Add a new node with corresponding value
  194. TreeNode freq = new TreeNode(temp1.getValue() + temp2.getValue(),
  195. temp1, temp2);
  196. // Enqueue back into priorityQueue in correct position
  197. counts.enqueue(freq);
  198. size++;
  199. }
  200. }
  201.  
  202. // createMap method to create map
  203. private void createMap(HashMap<Integer, String> map, TreeNode n,
  204. String result) {
  205. // if node is a leaf, put into HashMap
  206. if (n.isLeaf()) {
  207. map.put(n.getValue(), result);
  208. // Else, continue traversing while adding node bit to result
  209. } else {
  210. createMap(map, n.getLeft(), result + "0");
  211. createMap(map, n.getRight(), result + "1");
  212. }
  213. }
  214.  
  215. // printMap method to output map
  216. public void printMap() {
  217. System.out.println("map: ");
  218. for (int x : map.keySet()) {
  219. System.out.println((char) x + " " + map.get(x));
  220. }
  221. System.out.println();
  222. }
  223.  
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement