I am having issues with determining the priority for each node that contains a char In order to decompress my compressed file.
So When I compress a file it gives me a txt file containing something like this:
I compressed: Hello world this is a test.
@111^a@10000^#@10001^d@10011^e@1010^H@0000^h@10110^i@1101^l@001^.@0001^o@1100^r@10010^s@011^t@010^w@10111^%
00001010001001110011110111110010010001100111110101011011010111111101011111100001110101010011010000110001
The first two lines have the binary representation of each character contained in the compressed file.
The second two lines are the actual compressed txt.
The compression class creates a tree by setting the priority of nodes equal to the number of occurrences.
However, The compression class does not write the number of occurrences for each character to the output file.
To determine priority I was thinking I could maybe do It by the length of the binary string for each character. If the length of the string is bigger then its used less frequently. On the other hand if it is smaller it is used more. However this didn't seem to construct the tree how I wanted it to as it gave me the wrong output.
I was able to get the right output by editing what the compressed file writes to the output file. Basically just passing in the characters frequencies as well. But how would I do this without having those values is my main question.
I was also thinking that I could just make the tree based on the actual Binary string for each character. Something like create a dummy root node. If charAt(i) in the string equals 0 go left else go right. I think my code may be a bit off for this because I get null pointer exceptions while trying to traverse the tree. Ill post the code below.
This is a short simple version version if needed I could post more
public class Decompress {
private static Node root;
private static HashMap<Character, String> values = new HashMap<Character, String>();
private static HashMap<Character, Integer> freq = new HashMap<Character, Integer>();
public Decompress() {
root = null;
}
private static class Node implements Comparable {
public Character value;
public Integer number;
public Node left;
public Node right;
// necessary in order for the priority queue to work
// since it uses the compareTo to determine priority.
public int compareTo(Object o) {
Node other = (Node) o;
if (other.number < number) {
return 1;
}
if (other.number == number) {
return 0;
}
return -1;
}
public static void main(String args[]) throws IOException {
BufferedReader fin = new BufferedReader(new FileReader("output" + ".txt"));
String binaryDigits = insertListHelper(fin); // contains the compressed txt
root = createTree(binaryDigits); // Grabs the root node from method
Node hold = root;
// code for traversing the tree to find the character
for (int i = 0; i < binaryDigits.length(); i++) {
if (binaryDigits.charAt(i) == '1') {
root = root.right;
} else if (binaryDigits.charAt(i) == '0') {
root = root.left;
}
if (root.left == null && root.right == null) {
System.out.println(root.value);
root = hold;
}
}
}
// works when I have the correct frequency
public static Node createTree(String binaryDigit) {
PriorityQueue<Node> pq = new PriorityQueue<Node>();
// insert all 1 node trees into pq
Set<Character> s = values.keySet();
for (Character c : s) {
Node temp = new Node();
temp.value = c;
temp.number = values.get(c).length();
temp.left = null;
temp.right = null;
pq.add(temp);
}
Node eof = new Node();
eof.value = '#';
eof.number = 1;
eof.left = null;
eof.right = null;
pq.add(eof);
while (pq.size() > 1) {
Node left = pq.poll();
Node right = pq.poll();
Node temp = new Node();
temp.value = null;
temp.number = left.number + right.number;
temp.left = left;
temp.right = right;
pq.add(temp);
}
return pq.peek();
}
// does not work any suggestions?
public static Node createTree2() {
String[] binaryRep = new String[values.size()];
int k = 0;
int lengthOfStr = 0;
Set<Character> s1 = values.keySet();
for (Character c : s1) {
binaryRep[k] = values.get(c);
System.out.println(c + " String : " + binaryRep[k]);
Node root = new Node();
root.value = 'R';
root.left = null;
root.right = null;
Node hold = root;
lengthOfStr = binaryRep[k].length();
for (int i = 0; i < binaryRep[k].length(); i++) {
if (binaryRep[k].charAt(i) == '1' && root.right != null) {
root = root.right;
} else if (binaryRep[k].charAt(i) == '0' && root.left != null) {
root = root.left;
} else if (binaryRep[k].charAt(i) == '1' && root.right == null && lengthOfStr == 0) {
// found our place to insert
Node temp = new Node();
temp.left = null;
temp.right = null;
temp.number = 1;
temp.value = c;
root.right = temp;
// move forward to the temp var
root = root.right;
root = hold;
lengthOfStr--;
} else if (binaryRep[k].charAt(i) == '0' && root.left == null && lengthOfStr == 0) { // should be a leaf
// node
// found our place to insert
Node temp = new Node();
temp.left = null;
temp.right = null;
temp.number = 0;
temp.value = c;
root.left = temp;
// move forward to the temp var
root = root.right;
root = hold;
lengthOfStr--;
} else if (binaryRep[k].charAt(i) == '1' && root.right == null) {
// found our place to insert
Node temp = new Node();
temp.left = null;
temp.right = null;
temp.number = 1;
temp.value = null;
root.right = temp;
// move forward to the temp var
root = root.right;
lengthOfStr--;
} else if (binaryRep[k].charAt(i) == '0' && root.left == null) {
// found our place to insert
Node temp = new Node();
temp.left = null;
temp.right = null;
temp.number = 0;
temp.value = null;
root.left = temp;
// move forward to the temp var
root = root.left;
lengthOfStr--;
}
}
k++;
}
return root;
}
}