Files
uni/ws2019/ipi/uebungen/cpp_headers/HuffmanSTL.cc
T

116 lines
2.8 KiB
C++

#include <iostream>
#include <map>
#include <queue>
#include <string>
using namespace std; // import namespace std
// There are no general binary trees in the STL.
// But we do not use much of this structure anyhow...
struct node {
struct node *left;
struct node *right;
char symbol;
int weight;
node (char c, int i) { // leaf constructor
symbol = c;
weight = i;
left = right = 0;
}
node (node* l, node *r) { // internal node constructor
symbol = 0;
weight = l->weight + r->weight;
left = l;
right = r;
}
bool isleaf() {return symbol!=0;}
bool operator> (const node &a) const {
return weight > a.weight;
}
};
// construct the Huffman trie for this message
node* huffman_trie (string message) {
// count multiplicities
map<char,int> cmap;
for (string::iterator i=message.begin(); i!=message.end(); i++)
if (cmap.find(*i)!=cmap.end())
cmap[*i]++;
else
cmap[*i]=1;
// generate leaves with multiplicities
priority_queue<node, vector<node>, greater<node> > q;
for (map<char,int>::iterator i=cmap.begin(); i!=cmap.end(); i++)
q.push(node(i->first,i->second));
// build Huffman tree (trie)
while (q.size()>1)
{
node *left = new node(q.top());
q.pop();
node *right = new node(q.top());
q.pop();
q.push(node(left, right));
}
return new node(q.top());
}
// recursive filling of the encoding table 'code'
void fill_encoding_table (string s, node *i,
map<char,string>& code) {
if (i->isleaf())
code[i->symbol]=s;
else
{
fill_encoding_table (s+"0", i->left, code);
fill_encoding_table (s+"1", i->right, code);
}
}
// encoding
string encode (map<char,string> code, string& message) {
string encoded = "";
for (string::iterator i=message.begin(); i!=message.end(); i++)
encoded += code[*i];
return encoded;
}
// decoding
string decode (node* trie, string& encoded) {
string decoded = "";
node* node = trie;
for (string::iterator i=encoded.begin(); i!=encoded.end(); i++)
{
if (!node->isleaf())
node = (*i=='0') ? node->left : node->right;
if (node->isleaf())
{
decoded.push_back(node->symbol);
node = trie;
}
}
return decoded;
}
int main () {
string message = "ABRACADABRASIMSALABIM";
// generate Huffman trie
node* trie = huffman_trie(message);
// generate and show encoding table
map<char,string> table;
fill_encoding_table ("", trie, table);
for (map<char,string>::iterator i=table.begin(); i!=table.end(); i++)
cout << i->first << " " << i->second << endl;
// encode and decode
string encoded = encode(table, message);
cout << "Encoded: " << encoded <<
" [" << encoded.size() << " Bits]" << endl ;
cout << "Decoded: " << decode(trie, encoded) << endl;
// the trie is not deleted here ...
}