RosettaCodeData/Task/Huffman-coding/JavaScript/huffman-coding-1.js

64 lines
1.6 KiB
JavaScript

function HuffmanEncoding(str) {
this.str = str;
var count_chars = {};
for (var i = 0; i < str.length; i++)
if (str[i] in count_chars)
count_chars[str[i]] ++;
else
count_chars[str[i]] = 1;
var pq = new BinaryHeap(function(x){return x[0];});
for (var ch in count_chars)
pq.push([count_chars[ch], ch]);
while (pq.size() > 1) {
var pair1 = pq.pop();
var pair2 = pq.pop();
pq.push([pair1[0]+pair2[0], [pair1[1], pair2[1]]]);
}
var tree = pq.pop();
this.encoding = {};
this._generate_encoding(tree[1], "");
this.encoded_string = ""
for (var i = 0; i < this.str.length; i++) {
this.encoded_string += this.encoding[str[i]];
}
}
HuffmanEncoding.prototype._generate_encoding = function(ary, prefix) {
if (ary instanceof Array) {
this._generate_encoding(ary[0], prefix + "0");
this._generate_encoding(ary[1], prefix + "1");
}
else {
this.encoding[ary] = prefix;
}
}
HuffmanEncoding.prototype.inspect_encoding = function() {
for (var ch in this.encoding) {
print("'" + ch + "': " + this.encoding[ch])
}
}
HuffmanEncoding.prototype.decode = function(encoded) {
var rev_enc = {};
for (var ch in this.encoding)
rev_enc[this.encoding[ch]] = ch;
var decoded = "";
var pos = 0;
while (pos < encoded.length) {
var key = ""
while (!(key in rev_enc)) {
key += encoded[pos];
pos++;
}
decoded += rev_enc[key];
}
return decoded;
}