-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPrefixCodeTable.java
More file actions
97 lines (86 loc) · 3.44 KB
/
PrefixCodeTable.java
File metadata and controls
97 lines (86 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import java.util.ArrayList;
/**
* This class represents a table that encodes binary strings to characters based of the HuffmanBinaryTree
* @see HuffmanBinaryTree
* @author Hudson Hadley
*/
public class PrefixCodeTable {
/**
* The characters we are encoding
*/
private ArrayList<Character> characters;
/**
* The codes we have encoded for each character
*/
private ArrayList<String> codes;
/**
* Constructs a PrefixCodeTable based on data stored in a Huffman binary tree
* @param huffmanBinaryTree the tree containing each character we want to encode
* @see HuffmanBinaryTree
*/
public PrefixCodeTable(HuffmanBinaryTree huffmanBinaryTree) {
characters = new ArrayList<>();
codes = new ArrayList<>();
Node root = huffmanBinaryTree.getRoot();
// If in our binary tree the root is a leaf, there is only one character
if (root.isExternal()) {
// Since there's only one character we can just declare the code to be "0"
characters.add(root.getValue());
codes.add("0");
} else { // If the tree is more extensive
generateCodes("", huffmanBinaryTree.getRoot());
}
}
/**
* Traverses through a current node using recursion and generates codes for each node.
* Only leaves are added to the characters and codes lists, but there does exist a code for each node.
* Starting with the currentCode, if we take a left we add a 0 to the beginning, and if we take a right
* we add a 1 to the beginning.
* @param currentCode the code we have at the current node. If it is the first time calling, it will be ""
* @param node the current node we are at
*/
private void generateCodes(String currentCode, Node node) {
// If it is a leaf, we want to add the character and code
if (node.isExternal()) {
characters.add(node.getValue());
codes.add(currentCode);
} else { // If it is not a leaf, all we care about are its children
generateCodes(currentCode + "0", node.getLeft());
generateCodes(currentCode + "1", node.getRight());
}
}
/**
* @param c the character we want to look up
* @return the encoding of the character
* @throws IllegalArgumentException if the character is not found
*/
public String getCode(char c) throws IllegalArgumentException {
int index = characters.indexOf(c);
if (index == -1)
throw new IllegalArgumentException("Character not found");
return codes.get(index);
}
/**
* @param code the code of the character we want to look up
* @return the character with the correct code
* @throws IllegalArgumentException if the code is not found
*/
public char getChar(String code) throws IllegalArgumentException {
int index = codes.indexOf(code);
// If we cannot find the code
if (index == -1)
throw new IllegalArgumentException("Code not found");
return characters.get(index);
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < characters.size(); i++) {
stringBuilder.append(characters.get(i));
stringBuilder.append(": ");
stringBuilder.append(codes.get(i));
stringBuilder.append("\n");
}
return stringBuilder.toString();
}
}