-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Expand file tree
/
Copy pathHuffmanCoder.java
More file actions
103 lines (83 loc) · 2.37 KB
/
HuffmanCoder.java
File metadata and controls
103 lines (83 loc) · 2.37 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
98
99
100
101
102
103
import java.util.*;
class HuffmanCoder {
HashMap<Character, String> encoder;
HashMap<String, Character> decoder;
private class Node implements Comparable<Node> {
Character data;
int cost; // frequency
Node left;
Node right;
public Node(Character data, int cost) {
this.data = data;
this.cost = cost;
this.left = null;
this.right = null;
}
@Override
public int compareTo(Node other) {
return this.cost - other.cost;
}
}
public HuffmanCoder(String feeder) throws Exception {
HashMap<Character, Integer> fmap = new HashMap<>();
for(int i=0; i < feeder.length(); i++) {
char cc = feeder.charAt(i);
if(fmap.containsKey(cc)) {
int ov = fmap.get(cc);
ov += 1;
fmap.put(cc, ov);
} else {
fmap.put(cc, 1);
}
}
Heap<Node> minHeap = new Heap<>();
Set<Map.Entry<Character, Integer>> entrySet = fmap.entrySet();
for(Map.Entry<Character, Integer> entry : entrySet) {
Node node = new Node(entry.getKey(), entry.getValue());
minHeap.insert(node);
}
while(minHeap.size() != 1) {
Node first = minHeap.remove();
Node second = minHeap.remove();
Node newNode = new Node('\0', first.cost + second.cost);
newNode.left = first;
newNode.right = second;
minHeap.insert(newNode);
}
Node ft = minHeap.remove();
this.encoder = new HashMap<>();
this.decoder = new HashMap<>();
this.initEncoderDecoder(ft, "");
}
private void initEncoderDecoder(Node node, String osf) {
if(node == null) {
return;
}
if(node.left == null && node.right == null) {
this.encoder.put(node.data, osf);
this.decoder.put(osf, node.data);
}
initEncoderDecoder(node.left, osf+"0");
initEncoderDecoder(node.right, osf+"1");
}
public String encode(String source) {
String ans = "";
// Bitset can be used: like an array but with a bit at each index
for(int i=0; i<source.length(); i++) {
ans = ans + encoder.get(source.charAt(i));
}
return ans;
}
public String decode(String encodedString) {
String key = "";
String ans = "";
for(int i=0; i<encodedString.length(); i++) {
key = key + encodedString.charAt(i);
if(decoder.containsKey(key)) {
ans = ans + decoder.get(key);
key = "";
}
}
return ans;
}
}