Update huffman coding.

This commit is contained in:
Jacob Signorovitch
2025-01-14 12:59:51 -05:00
parent b6ec810bb9
commit 8a264d7dfc

View File

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