diff --git a/dynamicprogramming/java/src/com/com/brainbaking/greedy/Huffman.java b/dynamicprogramming/java/src/com/com/brainbaking/greedy/Huffman.java new file mode 100644 index 0000000..933b51c --- /dev/null +++ b/dynamicprogramming/java/src/com/com/brainbaking/greedy/Huffman.java @@ -0,0 +1,72 @@ +package com.com.brainbaking.greedy; + +import java.util.*; +import java.util.stream.Collectors; + +public class Huffman { + + private final String toEncode; + private final Node root; + + public Huffman(String toEncode) { + this.toEncode = toEncode; + + root = buildMinRoot(buildQueue()); + } + + private Node buildMinRoot(Queue nodes) { + Node root = null; + + while(nodes.size() > 1) { + Node first = nodes.poll(); + Node second = nodes.poll(); + + root = new Node(first, second); + nodes.add(root); + } + + // in geval van maar 1 karakter + return root == null ? nodes.poll() : root; + } + + private Queue buildQueue() { + Set chars = buildCharSet(); + Queue tree = new PriorityQueue<>(); + + for(Integer character : chars) { + int frequency = (int) toEncode.chars().filter(c -> c == character).count(); + tree.add(new Node(character, frequency)); + } + return tree; + } + + private Set buildCharSet() { + return toEncode.chars().boxed().collect(Collectors.toSet()); + } + + public String encode() { + Map encodeMap = new HashMap<>(); + buildEncodedMap(root, encodeMap, ""); + + String encoded = ""; + for(int i = 0; i < toEncode.length(); i++) { + encoded += encodeMap.get(toEncode.charAt(i)); + } + return encoded; + + // wat is hier mis mee? + //return toEncode.chars().mapToObj(c -> encodeMap.get(c)).collect(Collectors.joining()); + } + + private void buildEncodedMap(Node node, Map map, String encoded) { + if(node.isRoot()) { + // in geval van maar 1 karakter + map.put(node.getCharacter(), encoded.equals("") ? "0" : encoded); + return; + } + + buildEncodedMap(node.getLeft(), map, encoded + "0"); + buildEncodedMap(node.getRight(), map, encoded + "1"); + } + +} diff --git a/dynamicprogramming/java/src/com/com/brainbaking/greedy/Node.java b/dynamicprogramming/java/src/com/com/brainbaking/greedy/Node.java new file mode 100644 index 0000000..28fed59 --- /dev/null +++ b/dynamicprogramming/java/src/com/com/brainbaking/greedy/Node.java @@ -0,0 +1,47 @@ +package com.com.brainbaking.greedy; + +public class Node implements Comparable { + + private final char character; + private final int frequency; + + private Node left; + private Node right; + + public boolean isRoot() { + return left == null && right == null; + } + + public Node getLeft() { + return left; + } + + public Node getRight() { + return right; + } + + public char getCharacter() { + return character; + } + + public int getFrequency() { + return frequency; + } + + public Node(Node left, Node right) { + this.left = left; + this.right = right; + this.character = '-'; + this.frequency = left.getFrequency() + right.getFrequency(); + } + + public Node(Integer character, int frequency) { + this.character = (char) character.intValue(); + this.frequency = frequency; + } + + @Override + public int compareTo(Node o) { + return frequency - o.frequency; + } +} diff --git a/dynamicprogramming/java/test/com/brainbaking/greedy/HuffmanTest.java b/dynamicprogramming/java/test/com/brainbaking/greedy/HuffmanTest.java new file mode 100644 index 0000000..107a2d4 --- /dev/null +++ b/dynamicprogramming/java/test/com/brainbaking/greedy/HuffmanTest.java @@ -0,0 +1,36 @@ +package com.brainbaking.greedy; + +import com.com.brainbaking.greedy.Huffman; +import org.junit.Test; + +import static junit.framework.TestCase.assertEquals; + +public class HuffmanTest { + + @Test + public void huffman_OnlyOnCharacter() { + Huffman huffman = new Huffman("aaa"); + + String result = huffman.encode(); + + assertEquals("000", result); + } + + @Test + public void huffman_charAFrequences5TimesButBAndCOnlyOnce() { + Huffman huffman = new Huffman("baaaaac"); + + String result = huffman.encode(); + + assertEquals("001111101", result); + } + + @Test + public void huffmanEncoded() { + Huffman huffman = new Huffman("hallo dit is een test wasda jong"); + + String result = huffman.encode(); + + assertEquals("110001101100110011000111101110100101111010000111001001011011101000100001011111001110100010111101111011111000011001110", result); + } +}