Project Description:
Project Description: The use of Huffman coding of the file compression, and the compressed file can be decompressed
Development environment: Windows vs2013
Project Overview:
1. Compress
A. Read the file, will each character, the number of occurrences and weights of the character constitute Huffman tree
B. Huffman tree is the use of small heap composition, the number of characters appear in the node pointer to the top of the heap, the occurrence of more times in the heap bottom
C. Each two number of the top of the heap, and then add two numbers into the heap, until the heap is finished, then Huffman Tree also built
D. Get Huffman code from Huffman Tree, then get the code of the character by the whole character array
E. After obtaining the encoding, writes the code string to the compressed file each time it reaches 8 bits (value processing code 1 and it can, 0 moves bit)
F. Write a profile, count each character and its occurrences, and save it to the configuration file as "character +", ' + Times '
2. Decompression
A. Read the configuration file and count all the characters
B. Build Huffman tree, read the uncompressed file, read the encoded characters of this node contains characters written to the decompression file, know the compressed file read
C. Compression decompression complete, small file large file test
#pragma once #include <vector> template<class t> struct Less {bool operator () (const t& L, const t& R
) Const {return L < R;
}
};
Template<class t> struct Greater {bool operator () (const t& L, const t& R) Const {return L > r;
}
}; Template<class T, Class compare> class Heap {public:heap () {} Heap (t* array, size_t N)//build Heap {_array.re
Serve (n);
for (size_t i = 0; i < n; i++) {_array.push_back (array[i));
for (int i = (_array.size ()-2) >> 1; I >= 0;-i) {_adjustdown (i);
} const t& Top () const {return _array[0];
} void Push (const t& x) {_array.push_back (x);
_adjustup (_array.size ()-1);
} size_t Size () {return _array.size ();
} void Pop () {assert (_array.size () > 0);
Swap (_array[0], _array[_array.size ()-1]);
_array.pop_back ();
_adjustdown (0);
BOOL Empty () {return _array.size () = 0; } void Print () {for (size_t i = 0; i< _array.size ();
++i) {cout << _array[i] << "";
} cout << Endl;
} protected:void _adjustup (int child)//raise {Compare comfunc;
int parent = (child-1) >> 1;
while (child) {if (Comfunc (_array[child], _array[parent])) ({swap (_array[child), _array[parent]);
Child = parent;
Parent = (child-1) >> 1;
} else {break;
}} void _adjustdown (int root)//downgrade {Compare comfunc;
int parent = root;
int child = root * 2 + 1; while (Child < _array.size ()) {if child + 1 < _array.size () && comfunc (_array[child + 1], _array[chil
D]) {++child;
} if (Comfunc (_array[child], _array[parent])) {swap (_array[child), _array[parent]);
parent = child;
Child = parent * 2 + 1;
} else {break;
}} protected:vector<t> _array;
};
void Testheap () {int a[] = {10, 11, 13, 12, 16, 18, 15, 17, 14, 19}; Heap<int> HeaP (A, sizeof (a)/sizeof (a[0));
Heap<int, Less<int>> Heap (A, sizeof (a)/sizeof (a[0));
Heap<int, Greater<int>> Heap (A, sizeof (a)/sizeof (a[0)); Heap.
Print (); Heap.
Push (25); Heap.
Print (); Heap.
Pop (); Heap.
Print (); }
#pragma once #include "Heap.h" template<class t> struct Huffmantreenode {huffmantreenode<t>* _left;
huffmantreenode<t>* _right;
huffmantreenode<t>* _parent; T _w;
Weighted value Huffmantreenode (const t& x): _w (x), _left (null), _right (null), _parent (null) {}};
Template<class T> class Huffmantree {typedef huffmantreenode<t> Node; Public:huffmantree (): _root (NULL) {} huffmantree (t* A, size_t N, const t& invalid = T ())//Build Huffman tree {struct Compare {bool operator () (node*
L, node* R) Const {return L->_w < r->_w;
}
};
heap<node*, compare> minheap;
for (size_t i = 0; i < n; ++i) {if (a[i)!= invalid) {Minheap.push (new Node (a[i));
} while (Minheap.size () > 1) {node* left = Minheap.top ();
Minheap.pop ();
node* right = Minheap.top ();
Minheap.pop ();
node* parent = new Node (Left->_w + right->_w);
Parent->_left = left; PaRent->_right = right;
Left->_parent = parent;
Right->_parent = parent;
Minheap.push (parent);
} _root = Minheap.top ();
} node* Getroot () {return _root;
} ~huffmantree () {_destory (_root);
} protected:void _destory (node* root) {if (root = NULL) {return;
} _destory (Root->_left);
_destory (Root->_right);
Delete root;
} huffmantree (const huffmantree<t>& tree);
huffmantree& operator= (const huffmantree<t>& tree);
protected:node* _root;
}; void Testhuffmantree () {
#pragma once #include <iostream> using namespace std;
#include <assert.h> #include "HuffmanTree.h" typedef long long Longtype; struct Charinfo {unsigned char _ch; Character Longtype _count; The number of occurrences of the character string _code; Huffman encoding Charinfo (longtype count = 0): _count (count), _ch (0), _code ("") {} bool operator< (const Charin
fo& info) Const {return _count < Info._count;
} charinfo operator+ (const charinfo& info) {return charinfo (_count + info._count);
BOOL Operator!= (const charinfo& info) Const {return _count!= info._count;
}
}; struct Countinfo {unsigned char _ch; Character Longtype _count;
The number of occurrences of the character};
Class Filecompress {public:filecompress () {for (size_t i = 0; i < 256; ++i) {_info[i]._ch = i;
} void Compress (const char* filename) {assert (filename);
The number of occurrences of a statistic character has been read and written in binary mode file* fout = fopen (filename, "RB");
ASSERT (Fout); int ch = fgetc (fout);
string compressfile = filename;
Compressfile = ". Huffman";
file* fin = fopen (Compressfile.c_str (), "WB");
ASSERT (Fin);
Countinfo info;
while (Ch!= EOF) {_info[(unsigned char) ch]._count++;
ch = fgetc (fout);
}//Build Huffman tree Charinfo Invalid;
Invalid._count = 0;
Huffmantree<charinfo> Tree (_info, 256, invalid); Generates Huffman code Gethuffmancode (tree.
Getroot ());
Compressed//write configuration file for (size_t i = 0; i < 256 ++i) {if (_info[i]._count) {info._ch = _info[i]._ch;
Info._count = _info[i]._count;
Fwrite (&info, sizeof (info), 1, Fin);
} Info._count =-1;
Fwrite (&info, sizeof (info), 1, Fin); Fseek (fout, 0, Seek_set);
Return to file Start ch = fgetc (fout); char value = 0; binary int pos = 0;
Left shift number while (CH!= EOF) {string& code = _info[(unsigned char) ch]._code;
size_t i = 0;
for (i = 0; i < code.size (); ++i) {value <<= 1;
++pos; if (code[i] = =' 1 ') {value |= 1;
The IF (pos = 8)/full 8-bit is written into the file {FPUTC (value, fin);
Value = 0;
pos = 0;
{ch = fgetc (fout);
} if (POS) {value <<= (8-pos);
FPUTC (value, fin);
} fclose (Fin);
Fclose (Fout);
} void Gethuffmancode (huffmantreenode<charinfo>* root)//huffman encoding {if (root = NULL) {return;
} if (root->_left = = NULL && Root->_right = null) {huffmantreenode<charinfo> *parent, *cur;
cur = root;
Parent = cur->_parent;
string& code = _info[(unsigned char) root->_w._ch]._code;
while (parent) {if (cur = = parent->_left) {code = ' 0 ';
else {code = ' 1 ';
} cur = parent;
Parent = cur->_parent;
} reverse (Code.begin (), Code.end ());
} gethuffmancode (Root->_left);
Gethuffmancode (Root->_right);
}//extract void uncompress (const char* filename) {assert (filename); String UNcompressfile = filename;
size_t index = Uncompressfile.rfind ('. ');
ASSERT (index!= string::npos);
Uncompressfile = uncompressfile.substr (0, index);
Uncompressfile = ". Unhuffman";
file* fout = fopen (filename, "RB");
ASSERT (Fout);
file* fin = fopen (Uncompressfile.c_str (), "WB");
ASSERT (Fin);
Countinfo info;
Fread (&info, sizeof (Countinfo), 1, fout);
Read configuration information while (1) {fread (&info, sizeof (Countinfo), 1, fout);
if (Info._count = = 1) {break;
} _info[(unsigned char) info._ch]._ch = info._ch;
_info[(unsigned char) info._ch]._count = Info._count;
}//Rebuild Huffman tree Charinfo invalid;
Invalid._count = 0;
Huffmantree<charinfo> Tree (_info, 256, invalid); huffmantreenode<charinfo>* root = tree.
Getroot ();
huffmantreenode<charinfo>* cur = root;
Longtype count = root->_w._count;
int value = FGETC (Fout);
if (value = = EOF)///Only one character {if (info._ch!= 0) {while (cur->_w._count--) {FPUTC (cur->_w._ch, Fin);
}} else {while (value!= EOF) {int pos = 7;
char test = 1;
while (POS >= 0) {if (Value & (Test << pos)) {cur = cur->_right;
else {cur = cur->_left;
} if (cur->_left = = NULL && Cur->_right = null) {FPUTC (cur->_w._ch, Fin);
cur = root;
if (--count = = 0) {break;
}}--pos;
} value = Fgetc (Fout);
} fclose (Fout);
Fclose (Fin); } protected:charinfo _info[256];
all character information};
void Testfilecompress () {filecompress FC;
Fc.compress ("experiment. Doc"); Fc.
Uncompress ("experiment. Doc.huffman"); Fc.compress ("QQ").
JPG "); Fc. Uncompress ("QQ").
Jpg.huffman ");
Fc.compress ("www.MP3"); Fc.
Uncompress ("Www.MP3.huffman");
Fc.compress ("Yppppp.txt"); Fc.
Uncompress ("Yppppp.txt.huffman"); }
int array[10] = {2, 4, 6, 9, 7, 8, 5, 0, 1, 3}; Huffmantree<int> T (array, 10);}
#include <iostream>
#include <assert.h>
#include <windows.h>
using namespace std;
#include "Heap.h"
#include "HuffmanTree.h"
#include "FileCompress.h"
int main ()
{
//testheap () ;
Testhuffmantree ();
Testfilecompress ();
System ("pause");
return 0;
}