Advertisement
Guest User

Untitled

a guest
Jan 17th, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 8.14 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public final class Huffman {
  5.  
  6.     private Huffman() {};
  7.  
  8.     private static class HuffmanNode {
  9.         char ch;
  10.         int frequency;
  11.         HuffmanNode left;
  12.         HuffmanNode right;
  13.  
  14.         HuffmanNode(char ch, int frequency,  HuffmanNode left,  HuffmanNode right) {
  15.             this.ch = ch;
  16.             this.frequency = frequency;
  17.             this.left = left;
  18.             this.right = right;
  19.         }
  20.     }
  21.  
  22.     private static class HuffManComparator implements Comparator<HuffmanNode> {
  23.         @Override
  24.         public int compare(HuffmanNode node1, HuffmanNode node2) {
  25.             return node1.frequency - node2.frequency;
  26.         }
  27.     }
  28.  
  29.     public static void compress(String sentence) throws FileNotFoundException, IOException {
  30.         if (sentence == null) {
  31.             throw new NullPointerException("Input sentence cannot be null.");
  32.         }
  33.         if (sentence.length() == 0) {
  34.             throw new IllegalArgumentException("The string should atleast have 1 character.");
  35.         }
  36.  
  37.         final Map<Character, Integer> charFreq = getCharFrequency(sentence);
  38.         final HuffmanNode root = buildTree(charFreq);
  39.  
  40.         System.out.println("Tree: ");
  41.  
  42.         final Map<Character, String> charCode = generateCodes(charFreq.keySet(), root);
  43.         final String encodedMessage = encodeMessage(charCode, sentence);
  44.  
  45.         System.out.println("Encoded message: " + encodedMessage);
  46.  
  47.         serializeTree(root);
  48.         serializeMessage(encodedMessage);
  49.     }
  50.  
  51.     private static Map<Character, Integer> getCharFrequency(String sentence) {
  52.         final Map<Character, Integer> map = new HashMap<Character, Integer>();
  53.  
  54.         for (int i = 0; i < sentence.length(); i++) {
  55.             char ch = sentence.charAt(i);
  56.             if (!map.containsKey(ch)) {
  57.                 map.put(ch, 1);
  58.             } else {
  59.                 int val = map.get(ch);
  60.                 map.put(ch, ++val);
  61.             }
  62.         }
  63.  
  64.         return map;
  65.     }
  66.  
  67.     private static HuffmanNode buildTree(Map<Character, Integer> map) {
  68.         final Queue<HuffmanNode> nodeQueue = createNodeQueue(map);
  69.  
  70.         while (nodeQueue.size() > 1) {
  71.             final HuffmanNode node1 = nodeQueue.remove();
  72.             final HuffmanNode node2 = nodeQueue.remove();
  73.             HuffmanNode node = new HuffmanNode('\0', node1.frequency + node2.frequency, node1, node2);
  74.             nodeQueue.add(node);
  75.         }
  76.  
  77.         return nodeQueue.remove();
  78.     }
  79.  
  80.     private static Queue<HuffmanNode> createNodeQueue(Map<Character, Integer> map) {
  81.         final Queue<HuffmanNode> pq = new PriorityQueue<HuffmanNode>(11, new HuffManComparator());
  82.         for (Map.Entry<Character, Integer> entry : map.entrySet()) {
  83.             pq.add(new HuffmanNode(entry.getKey(), entry.getValue(), null, null));
  84.         }
  85.         return pq;
  86.     }
  87.  
  88.     private static Map<Character, String> generateCodes(Set<Character> chars, HuffmanNode node) {
  89.         final Map<Character, String> map = new HashMap<Character, String>();
  90.         doGenerateCode(node, map, "");
  91.         return map;
  92.     }
  93.  
  94.  
  95.     private static void doGenerateCode(HuffmanNode node, Map<Character, String> map, String s) {
  96.         if (node.left == null && node.right == null) {
  97.             map.put(node.ch, s);
  98.             System.out.println(node.ch + ": " + s);
  99.             return;
  100.         }
  101.         doGenerateCode(node.left, map, s + '0');
  102.         doGenerateCode(node.right, map, s + '1' );
  103.     }
  104.  
  105.  
  106.     private static String encodeMessage(Map<Character, String> charCode, String sentence) {
  107.         final StringBuilder stringBuilder = new StringBuilder();
  108.  
  109.         for (int i = 0; i < sentence.length(); i++) {
  110.             stringBuilder.append(charCode.get(sentence.charAt(i)));
  111.         }
  112.         return stringBuilder.toString();
  113.     }
  114.  
  115.     private static void serializeTree(HuffmanNode node) throws FileNotFoundException, IOException {
  116.         final BitSet bitSet = new BitSet();
  117.         try (ObjectOutputStream oosTree = new ObjectOutputStream(new FileOutputStream("/Users/ruslankirilyuk/tree"))) {
  118.             try (ObjectOutputStream oosChar = new ObjectOutputStream(new FileOutputStream("/Users/ruslankirilyuk/char"))) {
  119.                 IntObject o = new IntObject();
  120.                 preOrder(node, oosChar, bitSet, o);
  121.                 bitSet.set(o.bitPosition, true);
  122.                 oosTree.writeObject(bitSet);
  123.             }
  124.         }
  125.     }
  126.  
  127.     private static class IntObject {
  128.         int bitPosition;
  129.     }
  130.  
  131.     private static void preOrder(HuffmanNode node, ObjectOutputStream oosChar, BitSet bitSet, IntObject intObject) throws IOException {
  132.         if (node.left == null && node.right == null) {
  133.             bitSet.set(intObject.bitPosition++, false);
  134.             oosChar.writeChar(node.ch);
  135.             return;
  136.         }
  137.         bitSet.set(intObject.bitPosition++, true);
  138.         preOrder(node.left, oosChar, bitSet, intObject);
  139.  
  140.         bitSet.set(intObject.bitPosition++, true);
  141.         preOrder(node.right, oosChar, bitSet, intObject);
  142.     }
  143.  
  144.     private static void serializeMessage(String message) throws IOException {
  145.         final BitSet bitSet = getBitSet(message);
  146.  
  147.         try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("/Users/ruslankirilyuk/encodedMessage"))){
  148.  
  149.             oos.writeObject(bitSet);
  150.         }
  151.     }
  152.  
  153.     private static BitSet getBitSet(String message) {
  154.         final BitSet bitSet = new BitSet();
  155.         int i = 0;
  156.         for (i = 0; i < message.length(); i++) {
  157.             if (message.charAt(i) == '0') {
  158.                 bitSet.set(i, false);
  159.             } else {
  160.                 bitSet.set(i, true);
  161.             }
  162.         }
  163.         bitSet.set(i, true);
  164.         return bitSet;
  165.     }
  166.  
  167.     public static String expand() throws FileNotFoundException, ClassNotFoundException, IOException {
  168.         final HuffmanNode root = deserializeTree();
  169.         return decodeMessage(root);
  170.     }
  171.  
  172.     private static HuffmanNode deserializeTree() throws FileNotFoundException, IOException, ClassNotFoundException {
  173.         try (ObjectInputStream oisBranch = new ObjectInputStream(new FileInputStream("/Users/ruslankirilyuk/tree"))) {
  174.             try (ObjectInputStream oisChar = new ObjectInputStream(new FileInputStream("/Users/ruslankirilyuk/char"))) {
  175.                 final BitSet bitSet = (BitSet) oisBranch.readObject();
  176.                 return preOrder(bitSet, oisChar, new IntObject());
  177.             }
  178.         }
  179.     }
  180.  
  181.     private static HuffmanNode preOrder(BitSet bitSet, ObjectInputStream oisChar, IntObject o) throws IOException {
  182.         final HuffmanNode node = new HuffmanNode('\0', 0, null, null);
  183.  
  184.         if (!bitSet.get(o.bitPosition)) {
  185.             o.bitPosition++;
  186.             node.ch = oisChar.readChar();
  187.             return node;
  188.         }
  189.  
  190.         o.bitPosition = o.bitPosition + 1;
  191.         node.left = preOrder(bitSet, oisChar, o);
  192.  
  193.         o.bitPosition = o.bitPosition + 1;
  194.         node.right = preOrder(bitSet, oisChar, o);
  195.  
  196.         return node;
  197.     }
  198.  
  199.     private static String decodeMessage(HuffmanNode node) throws FileNotFoundException, IOException, ClassNotFoundException {
  200.         try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("/Users/ruslankirilyuk/encodedMessage"))) {
  201.             final BitSet bitSet = (BitSet) ois.readObject();
  202.             final StringBuilder stringBuilder = new StringBuilder();
  203.             for (int i = 0; i < (bitSet.length() - 1);) {
  204.                 HuffmanNode temp = node;
  205.  
  206.                 while (temp.left != null) {
  207.                     if (!bitSet.get(i)) {
  208.                         temp = temp.left;
  209.                     } else {
  210.                         temp = temp.right;
  211.                     }
  212.                     i = i + 1;
  213.                 }
  214.                 stringBuilder.append(temp.ch);
  215.             }
  216.             return stringBuilder.toString();
  217.         }
  218.     }
  219.  
  220.     public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
  221.         Huffman.compress("Kirilyuk Ruslan Dmitrievich");
  222.         System.out.println(Huffman.expand());
  223.     }
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement