Update huffman coding.

This commit is contained in:
Jacob Signorovitch
2025-01-14 12:59:51 -05:00
parent b6ec810bb9
commit 8a264d7dfc
+40 -28
View File
@@ -150,8 +150,8 @@ class Examples {
t.checkExpect( t.checkExpect(
h2.code, h2.code,
new Node(15, new Node(15,
new Node(6, new Node(3, new Leaf(1, "a"), new Leaf(2, "b")), new Node(6, new Leaf(3, "c"),
new Leaf(3, "c")), new Node(3, new Leaf(1, "a"), new Leaf(2, "b"))),
new Node(9, new Leaf(4, "d"), new Leaf(5, "e")))); new Node(9, new Leaf(4, "d"), new Leaf(5, "e"))));
} }
@@ -167,29 +167,41 @@ class Examples {
2, 2,
new Leaf(1, "h"), // // new Leaf(1, "h"), // //
new Leaf(1, "e")), new Leaf(1, "e")),
new Leaf(2, "o")), new Node(
2,
new Leaf(1, "w"), // //
new Leaf(1, "r"))),
new Node( new Node(
6, 6,
new Leaf(3, "l"), // //
new Node( new Node(
3, 3,
new Leaf(1, "d"), // // new Leaf(1, "d"), // //
new Node( new Leaf(2, "o")))));
2,
new Leaf(1, "w"), // //
new Leaf(1, "r"))),
new Leaf(3, "l"))));
ArrayList<Boolean> path = ArrayList<Boolean> path =
new ArrayList<>(Arrays.asList(false, false, false)); new ArrayList<>(Arrays.asList(false, false, false));
ArrayList<Boolean> path2 = ArrayList<Boolean> path2 =
new ArrayList<>(Arrays.asList(false, false, false, false, false, true, new ArrayList<>(Arrays.asList(false, false, false, // h
true, true, true, true, false, true)); false, false, true, // e
true, false, // l
true, false, // l
true, true, true // o
));
ArrayList<Boolean> path3 = new ArrayList<>( ArrayList<Boolean> path3 =
Arrays.asList(false, false, false, false, false, true, true, true, true, new ArrayList<>(Arrays.asList(false, false, false, // h
true, false, true, true, false, true, false, false, true, false, false, true, // e
true, false, true, true, true, true, true, false, false)); true, false, // l
true, false, // l
true, true, true, // o
false, true, false, // w
true, true, true, // o
false, true, true, // r
true, false, // l
true, true, false // d
));
t.checkExpect(huff.encode("h"), path); t.checkExpect(huff.encode("h"), path);
t.checkExpect(huff.decode(path), "h"); t.checkExpect(huff.decode(path), "h");
@@ -228,10 +240,10 @@ class Huffman {
this.map = new ArrayList<>(); this.map = new ArrayList<>();
// Generate the code. // Generate the code.
this.mkcode(); this.makeCode();
// Generate map. // Generate map.
this.mkmap(); this.makeMap();
} }
// Generates character freqs from string. // Generates character freqs from string.
@@ -259,25 +271,24 @@ class Huffman {
this.map = new ArrayList<>(); this.map = new ArrayList<>();
// Generate the code. // Generate the code.
this.mkcode(); this.makeCode();
// Generate map. // Generate map.
this.mkmap(); this.makeMap();
} }
// Creates the code tree. // Creates the code tree.
void mkcode() { void makeCode() {
ArrayList<ITree> nodes = new ArrayList<>(); ArrayList<ITree> nodes = new ArrayList<>();
// Copy all chars over as a tree leaves. // Copy all chars over as a tree leaves.
for (int i = 0; i < this.charset.size(); i++) for (int i = 0; i < this.charset.size(); i++)
nodes.add(new Leaf(this.freqs.get(i), this.charset.get(i))); nodes.add(new Leaf(this.freqs.get(i), this.charset.get(i)));
Util.sort(nodes);
// Combine until all under a single tree. // Combine until all under a single tree.
while (nodes.size() > 1) { while (nodes.size() > 1) {
// Sort the nodes.
Util.sort(nodes);
// Move the 2 lowest into their own tree. // Move the 2 lowest into their own tree.
ITree firstLowest = nodes.get(0); ITree firstLowest = nodes.get(0);
ITree secondLowest = nodes.get(1); ITree secondLowest = nodes.get(1);
@@ -287,7 +298,7 @@ class Huffman {
secondLowest); secondLowest);
// Put new tree into list. // Put new tree into list.
nodes.add(0, parent); Util.insertIntoSorted(parent, nodes);
} }
// Set the code to the first (and hopefully only) tree. // Set the code to the first (and hopefully only) tree.
@@ -295,7 +306,7 @@ class Huffman {
} }
// Make the character path mapping. // Make the character path mapping.
void mkmap() { void makeMap() {
for (String ch : this.charset) for (String ch : this.charset)
this.map.addLast(this.code.encode(ch)); this.map.addLast(this.code.encode(ch));
} }
@@ -395,13 +406,14 @@ class Node extends ATree {
} }
public String follow(ArrayList<Boolean> path) { public String follow(ArrayList<Boolean> path) {
ArrayList<Boolean> pathcpy = path;
String ret = ""; String ret = "";
// Each loop is 1 character. // Each loop is 1 character.
while (path.size() > 0) { while (pathcpy.size() > 0) {
Boolean b = path.getFirst(); Boolean b = pathcpy.getFirst();
path.removeFirst(); pathcpy.removeFirst();
ret += b ? this.r.followCh(path) : this.l.followCh(path); ret += b ? this.r.followCh(pathcpy) : this.l.followCh(pathcpy);
} }
return ret; return ret;