huffman mintree

This commit is contained in:
wgroeneveld 2018-04-01 10:47:29 +02:00
parent afee59b093
commit bee1b816cd
3 changed files with 155 additions and 0 deletions

View File

@ -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");
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}