Huffman coding and decoding
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>
#include <iomanip>
#include <queue>
#include <fstream>
using namespace std;
/*******************************************************************
* Define the tree-node
*******************************************************************/
class Node
{
public:
Node(char a,int b, Node *l, Node *r):data(a),freq(b) //Structor1
{
left = l;
right = r;
}
Node(const Node & n) //Structor2
{
data=n.data;
freq=n.freq;
left=n.left;
right=n.right;
}
bool operator < (const Node &n)const
{
return freq < n.freq;
}
bool operator == (const Node&n)const
{
return data == n.data;
}
char data;
int freq;
Node *left;
Node *right;
};
/*******************************************************************
* Define the Huffman Tree
*******************************************************************/
class HuffTree
{
public:
HuffTree() { root = NULL; } //Structor
~HuffTree(); //Destructor
HuffTree( vector<Node> ); //Create Huffman Tree according to the frequency map
void mkmap ( vector<Node> &node, string content);
void buildTree( vector<Node> node );
void Struct (char ch, string bits); //Create Huffman Tree according to the word-code map
void code(string filename); //read file and code
void code(Node* node, string s); //print word:code
void code(); //create code
void decode (fstream tree, fstream code); //create decode tree from file
void print(); //print the structure of the tree
void printTree(Node*,int indent); //print tree from a certain node
private:
Node *root;
};
/*******************************************************************
* Definition of Haffuman Tree
*******************************************************************/
HuffTree::~HuffTree()
{
//TODO
}
void HuffTree::mkmap( vector<Node> &node, string content) //make word-frequency map
{
node.clear();
for(unsigned int i=0;i<content.length();++i)
{
Node n(content.at(i),1,0,0);
vector<Node>::iterator result = find( node.begin(), node.end(), n );
if(result == node.end())
{
node.push_back(n);
}
else
result->freq += 1;
}
}
void HuffTree::code(string filename)
{
string content;
char ch;
ifstream readf;
readf.open(filename.c_str());
if(!readf.is_open())
{
cout<<"please check your filename (it consists of the path)"<<endl;
return;
}
while(!readf.eof())
{
readf.get(ch);
content += ch;
}
readf.close();
cout<<content;
vector<Node> node;
mkmap(node, content);
buildTree(node);
code();
}
void HuffTree::code(Node* node, string s)
{
if(NULL == node->left && NULL == node->right)
cout<<node->data<<':'<<s<<endl;
if(NULL != node->left)
code(node->left, s+'0');
if(NULL != node->right)
code(node->right,s+'1');
}
void HuffTree::code()
{
string s="";
code(root,s);
}
HuffTree::HuffTree( vector<Node> node)
{
buildTree (node);
}
void HuffTree::buildTree ( vector<Node> node )
{
Node *l = NULL;
Node *r = NULL;
vector<Node>::iterator current;
while(!node.empty())
{
current = min_element(node.begin(),node.end());
l = new Node(*current);
current = node.erase(current);
current = min_element(node.begin(),node.end());
r = new Node(*current);
current = node.erase(current);
root = new Node('*', l->freq + r->freq, l, r);
if(!node.empty())
node.push_back( *root );
}
}
void HuffTree::print()
{
queue <Node> q;
Node tmp(0,0,0,0);
q.push(*root);
while(!q.empty())
{
tmp = q.front();
q.pop();
cout<<tmp.data<<endl;
if(NULL != tmp.left)
q.push( *(tmp.left) );
if(NULL != tmp.right)
q.push( *(tmp.right) );
}
}
/*******************************************************************
* End of definition
*******************************************************************/
/*******************************************************************
* main function
* for test
*******************************************************************/
int main()
{
HuffTree huff;
string filename;
huff.code("change.txt");
cout << "Input filename:";
cin >> filename;
huff.code(filename);
return 0 ;
}
#include <algorithm>
#include <functional>
#include <vector>
#include <iomanip>
#include <queue>
#include <fstream>
using namespace std;
/*******************************************************************
* Define the tree-node
*******************************************************************/
class Node
{
public:
Node(char a,int b, Node *l, Node *r):data(a),freq(b) //Structor1
{
left = l;
right = r;
}
Node(const Node & n) //Structor2
{
data=n.data;
freq=n.freq;
left=n.left;
right=n.right;
}
bool operator < (const Node &n)const
{
return freq < n.freq;
}
bool operator == (const Node&n)const
{
return data == n.data;
}
char data;
int freq;
Node *left;
Node *right;
};
/*******************************************************************
* Define the Huffman Tree
*******************************************************************/
class HuffTree
{
public:
HuffTree() { root = NULL; } //Structor
~HuffTree(); //Destructor
HuffTree( vector<Node> ); //Create Huffman Tree according to the frequency map
void mkmap ( vector<Node> &node, string content);
void buildTree( vector<Node> node );
void Struct (char ch, string bits); //Create Huffman Tree according to the word-code map
void code(string filename); //read file and code
void code(Node* node, string s); //print word:code
void code(); //create code
void decode (fstream tree, fstream code); //create decode tree from file
void print(); //print the structure of the tree
void printTree(Node*,int indent); //print tree from a certain node
private:
Node *root;
};
/*******************************************************************
* Definition of Haffuman Tree
*******************************************************************/
HuffTree::~HuffTree()
{
//TODO
}
void HuffTree::mkmap( vector<Node> &node, string content) //make word-frequency map
{
node.clear();
for(unsigned int i=0;i<content.length();++i)
{
Node n(content.at(i),1,0,0);
vector<Node>::iterator result = find( node.begin(), node.end(), n );
if(result == node.end())
{
node.push_back(n);
}
else
result->freq += 1;
}
}
void HuffTree::code(string filename)
{
string content;
char ch;
ifstream readf;
readf.open(filename.c_str());
if(!readf.is_open())
{
cout<<"please check your filename (it consists of the path)"<<endl;
return;
}
while(!readf.eof())
{
readf.get(ch);
content += ch;
}
readf.close();
cout<<content;
vector<Node> node;
mkmap(node, content);
buildTree(node);
code();
}
void HuffTree::code(Node* node, string s)
{
if(NULL == node->left && NULL == node->right)
cout<<node->data<<':'<<s<<endl;
if(NULL != node->left)
code(node->left, s+'0');
if(NULL != node->right)
code(node->right,s+'1');
}
void HuffTree::code()
{
string s="";
code(root,s);
}
HuffTree::HuffTree( vector<Node> node)
{
buildTree (node);
}
void HuffTree::buildTree ( vector<Node> node )
{
Node *l = NULL;
Node *r = NULL;
vector<Node>::iterator current;
while(!node.empty())
{
current = min_element(node.begin(),node.end());
l = new Node(*current);
current = node.erase(current);
current = min_element(node.begin(),node.end());
r = new Node(*current);
current = node.erase(current);
root = new Node('*', l->freq + r->freq, l, r);
if(!node.empty())
node.push_back( *root );
}
}
void HuffTree::print()
{
queue <Node> q;
Node tmp(0,0,0,0);
q.push(*root);
while(!q.empty())
{
tmp = q.front();
q.pop();
cout<<tmp.data<<endl;
if(NULL != tmp.left)
q.push( *(tmp.left) );
if(NULL != tmp.right)
q.push( *(tmp.right) );
}
}
/*******************************************************************
* End of definition
*******************************************************************/
/*******************************************************************
* main function
* for test
*******************************************************************/
int main()
{
HuffTree huff;
string filename;
huff.code("change.txt");
cout << "Input filename:";
cin >> filename;
huff.code(filename);
return 0 ;
}

浙公网安备 33010602011771号