parent
afee59b093
commit
bee1b816cd
@ -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<Node> 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<Node> buildQueue() {
|
||||
Set<Integer> chars = buildCharSet();
|
||||
Queue<Node> 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<Integer> buildCharSet() {
|
||||
return toEncode.chars().boxed().collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
public String encode() {
|
||||
Map<Character, String> 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<Character,String> 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");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package com.com.brainbaking.greedy;
|
||||
|
||||
public class Node implements Comparable<Node> {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in new issue