Free Web Hosting Provider - Web Hosting - E-commerce - High Speed Internet - Free Web Page
Search the Web


                  Visitors : 5167 since Nov 14, 2002

                                   
   	[ Last Modification : 2004/07/31]
	---------------------------------

  Here is n-ary Huffman Template Algorithm.
  The algorithm has been written by Alex Vinokur.
  Programming Language : C++.
  Any and all comments would be appreciated.

	Alex Vinokur
	-----------------------------------
	alexvn@go.to
	http://up.to/alexvn
	http://alexvn.freeservers.com/s1/huffman_template_algorithm.html
	-----------------------------------
           
Find all about huffman coding
Find all about huffman coding

  Content.
    1. Algorithm
    2. Classes
    3. Program Files (Description)
    4. Tests (Description and Input Data Files)
    5. Program Files (Headers & Source)
    6. Compiling
    7. Running (Tests)
    8. Download

====================================================
=================== 1. Algorithm ===================
			       
1. n-ary Huffman algorithm uses 
   the {0, 1, ..., n-1} alphabet to encode message.
   Built tree is n-ary one.

2. Huffman template algorithm enables 
   to use non-numerical weights (costs, frequences).

   For more details see the discussion titled
        "Huffman codes with non-numerical cost?" 
        started 1999/02/22 in 
        * comp.dsp
        * comp.theory
        * sci.math

====================================================
====================================================
================ 2. List Of Classes ================

Main template classes used in the algorithm are as following :
     1. Cell<SYMBOL, WEIGHT>
     2. Node<SYMBOL, WEIGHT>
     3. InternalNode<SYMBOL, WEIGHT>
     4. TerminalNode<SYMBOL, WEIGHT>
     5. BasicHuffmanTree<SYMBOL, WEIGHT, ARY>
     ------------------------------------------
     6. LoadedHuffmanTree<SYMBOL, WEIGHT, ARY>
     7. DriedHuffmanTree<WEIGHT, ARY>
     ------------------------------------------

The user should use only
        LoadedHuffmanTree and/or
        DriedHuffmanTree classes.

LoadedHuffmanTree requires (as input data) the symbols and their weights.

DriedHuffmanTree requires (as input data) only the weights.
====================================================
====================================================
============= 3. List Of Program Files =============

The algorithm contains the following files :
     1. huf_service.H   auxiliary functions
     2. huf_class.H     template classes definition
     3. huf_methods.H   template methods description
     4. huf_main.C      tests; includes 
        4.1. Two test classes definition:
             - AAA ("symbol")
             - BBB ("weight")
        4.2. Main program
====================================================
====================================================
==== 4. Tests : Description and Input Data Files ===

The main program contains the following tests :
   Test#1.1.    Creating Loaded 5-ary Huffman Tree
                from data vector
                with char-symbols and int-weights

   Test#1.2.    Encoding and Decoding vector-message
                using 5-ary Huffman Tree

   Test#1.3.    Encoding and Decoding string-message
                using 5-ary Huffman Tree

   Test#2.      Creating Loaded 24-ary Huffman Tree
                from data vector
                with char-symbols and int-weights

   Test#3.1.    Creating Loaded Binary Huffman Tree
                from data vector
                with char-symbols and int-weights

   Test#3.2.    Encoding and Decoding vector-message
                using Binary Huffman Tree

   Test#3.3.    Encoding and Decoding string-message
                using Binary Huffman Tree

   Test#4.      Creating Dried (Unloaded) Binary Huffman Tree
                from data vector
                with int-weights
                Note. This vector contains Fibonacci sequence.
                    For more details about connection 
		    between Huffman codes and Fibonacci numbers
                    see the message titled
                    "Huffman codes and Fibonacci numbers" 
		    published 1999/04/28 in		    
		    * sci.math (http://forum.swarthmore.edu/epigone/sci.math/twalgixskay/)
                    * sci.crypt 
		    * comp.compression


   Test#5.      Creating Dried (Unloaded) Binary Huffman Tree
                from data file
                with int-weights
                File name is "weights_file_01"

   Test#6.      Creating Loaded Binary Huffman Tree
                from data file
                with char-symbols and int-weights
                File name is "data_file_01"

   Test#7.      Creating Loaded Binary Huffman Tree
                from data vector
                with string-symbols and float-weights

   Test#8.      Creating Loaded Binary Huffman Tree
                from data vector
                with AAA-symbols and BBB-weights



----- Test Data File "weights_file_01" -----
3
3
20
9
2
9
100
11
17
--------------------------------------------
----- Test Data File "data_file_01" --------
a       3
b       3
c       20
d       9
e       2
f       9
h       100
x       11
y       17
--------------------------------------------
====================================================
====================================================
================== 5. Program Files ================


#########################################################
=== File #1 of 4 : huf_service.H ========================------------------- C++ code : BEGIN --------------------
// ==============================================================
//
//  Copyright (c) 1999-2001 by Alex Vinokur.  This work and all works
//  derived from it may be copied and modified without any
//  restrictions other than that a copy of this copyright notice
//  must be included in any copy of this work or any derived work.
//
// ==============================================================

///////////////////////////////////////

#ifndef huf_service_H
#define huf_service_H

///////////////////////////////////////

static char id_huf_service_H[] = "@(#)## n-ary Huffman Template Algorithm ## Author : Alex Vinokur ## "__FILE__;

// ##############################################################
// =============================
//  n-ary Huffman Template Algorithm
//  The algorithm (program) contains the following files :
//  - huf_service.H
//  - huf_class.H
//  - huf_methods.H
//  - huf_main.C
// =============================
//
//  FILE : huf_service.H
//
//  AUTHOR : Alex Vinokur
//
//  DESCRIPTION :
//         Definition and implementation
//         of the following auxiliary template functions : 
//         ----------------------------------------------
//         - string             to_str (...)
//         - void               add_to_vector (...)
//         - void               fill_vector (...)
//         - unsigned int       get_width (...)
//         - string             gstr_vect_ptrs (...)
//         - string             gstr_vector (...)       // two functions
//         - string             gstr_path (...)
//         - string             gstr_map (...)
//         - ostream&           operator<< (...)        // two operators
//         ----------------------------------------------
//
//  DATE           VERSION
//  ----           -------
//  Aug-26-1999    NHTA 1.0
//  Jul-05-2001    NHTA 1.1
//  Sep-11-2001    NHTA 1.2
//
// ##############################################################


#include <strstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>
#include <algo.h>
#include <functional>
#include <iostream>
#include <fstream.h>
#include <typeinfo>
#include <iomanip.h>
#include <assert.h>


//#######################################################
//##### PART : DEFINES & CONSTANTS ######################
//#######################################################

#define MIN_VALUE(x,y)  ((x) < (y) ? (x) : (y))
#define MAX_VALUE(x,y)  ((x) > (y) ? (x) : (y))
#define ASSERT(x)       if (!(x)) {cerr << endl << endl << "\t=== BUG IN PROGRAM ===" << endl;}; assert (x)

#define FATAL_TITLE     "FATAL ERROR : "
#define FATAL_SHIFT     "            : "
#define FATAL_MSG(x)    cerr << endl \
                             << FATAL_TITLE \
                             << x \
                             << endl \
                             << FATAL_SHIFT \
                             << "File - " \
                             << __FILE__ \
                             << ", Line#" \
                             << __LINE__ \
                             << endl; \
                             exit (1)


#define ERROR_TITLE     "ERROR : "
#define ERROR_SHIFT     "      : "
#define ERROR_MSG(x)    cerr << endl \
                             << ERROR_TITLE \
                             << x \
                             << endl \
                             << ERROR_SHIFT \
                             << "File - " \
                             << __FILE__ \
                             << ", Line#" \
                             << __LINE__ \
                             << endl;


//#######################################################
//##### PART : typedefs #################################
//#######################################################
typedef unsigned int    CODE;



//#######################################################
//##### PART : FUNCTIONS ################################
//#######################################################


//#####################################################3
template <typename T>
string to_str (T value_i, int width_i = -1, char fill_i = ' ', const string& prefix_i = string ())
{
string          ret_stringValue;
strstream       tmp_strstream;

        //=================================
        if (width_i > 0)
        {
                tmp_strstream.width (width_i);
                tmp_strstream.fill (fill_i);
        }
        tmp_strstream << prefix_i;
        tmp_strstream << value_i;

        //=================================
        tmp_strstream << ends;
        ret_stringValue = tmp_strstream.str();
        tmp_strstream.rdbuf()->freeze (0);
        //=================================
        return ret_stringValue;
} // string to_str (T value_i)



//#####################################################3
template <typename T>
void add_to_vector (vector<T>& vector_i, const basic_string<T>& string_i)
{
        copy (string_i.begin (), string_i.end (), back_inserter (vector_i));
} //void add_to_vector (T value_o)



//#####################################################3
template <typename T>
void fill_vector (vector<T>& vector_i, const basic_string<T>& string_i)
{
        vector_i = vector<T> ();
        add_to_vector (vector_i, string_i);
} //void fill_vector (T value_o)




//#####################################################3
template <typename T>
unsigned int get_width (T value_i)
{
unsigned int    ret_intValue;
strstream       tmp_strstream;

        tmp_strstream << value_i;

        //=================================
        tmp_strstream << ends;
        ret_intValue = string (tmp_strstream.str()).size ();
        tmp_strstream.rdbuf()->freeze (0);
        //=================================
        return ret_intValue;
} // unsigned int get_width (T value_i)



//#####################################################
template <typename T1>
string   gstr_vect_ptrs (const vector<T1*>& vector_i, const string& delimiter_i = "")
{
strstream               tmp_strstream;
string                  tmp_string;
unsigned int            cur_index;

        cout << delimiter_i << endl;
        for (cur_index = 0; cur_index < vector_i.size (); cur_index++)
        {
                cout << "vector element ["
                     << cur_index << "] : "
                     << (*(vector_i [cur_index]))
                     << delimiter_i
                     << endl;
        }


        tmp_strstream << ends;
        tmp_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);

        //===================
        return tmp_string;

} // gstr_vect_ptrs (const vector<CODE>& vector_i)



//#####################################################
template <typename T1>
string   gstr_vector (const vector<T1>& vector_i, unsigned int start_pos_i = 0, unsigned int end_pos_i = UINT_MAX, const string& delimiter_i = "")
{

        if (vector_i.empty ())
        {
                return "Empty Vector";
        }
        //=====================================
        if (end_pos_i == UINT_MAX)
        {
                end_pos_i = vector_i.size () - 1;
        }
        ASSERT (end_pos_i < vector_i.size ());
        ASSERT (start_pos_i <= end_pos_i);
        //=====================================

strstream               tmp_strstream;
string                  tmp_string;
ostream_iterator<T1>    out (tmp_strstream, delimiter_i.c_str ());

        copy (vector_i.begin () + start_pos_i, vector_i.begin () + end_pos_i + 1, out);

        tmp_strstream << ends;
        tmp_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);

        //===================
        return tmp_string;

} // gstr_vector (const vector<CODE>& vector_i)



//#####################################################
template <typename T1>
ostream& operator<< (ostream& o, const vector<T1>& vector_i)
{
        return o << gstr_vector (vector_i);
}


//#####################################################
template <typename T1>
string   gstr_vector (const vector<T1>& vector_i, const string& delimiter_i, unsigned int start_pos_i = 0, unsigned int end_pos_i = UINT_MAX)
{
        return gstr_vector (vector_i, start_pos_i, end_pos_i, delimiter_i);
} // string   gstr_vector - 2


//#####################################################
template <unsigned int ARY>
string   gstr_path (const vector<CODE>& path_i)
{
const string    delimiter_CNS = (ARY > 16) ? "." : "";
strstream       tmp_strstream;
string          tmp_string;

        if (path_i.empty ())
        {
                tmp_strstream << "This is Huffman Tree Root";
        }
        else
        {
                for (unsigned int cur_index = 0; cur_index < path_i.size (); cur_index++)
                {
                        if (cur_index > 0)
                        {
                                tmp_strstream << delimiter_CNS;
                        }
                        tmp_strstream << path_i [cur_index];
                }
        }
        //=====================================
        tmp_strstream << ends;
        tmp_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);

        //===================
        return tmp_string;

} // gstr_path (const vector<CODE>& path_i)




//#######################################
template <typename T1, typename T2>
string gstr_map (const map<T1, T2, less<T1> >& map_i, const string &shift_i = string ())
{
strstream       tmp_strstream;
string          tmp_string;

        tmp_strstream << endl;
        tmp_strstream << endl;
        tmp_strstream << shift_i;
        tmp_strstream << "\tmap size = "
                      << map_i.size ()
                      << endl;

map<T1, T2, less<T1> >::const_iterator  cur_const_iter;
        for (cur_const_iter = map_i.begin(); !(cur_const_iter == map_i.end()); cur_const_iter++)
        {
                tmp_strstream << shift_i;
                tmp_strstream << "map element ["
                              << (*cur_const_iter).first
                              << "] = "
                              << "<"
                              << (*cur_const_iter).second
                              << ">";
                tmp_strstream << endl;
        }
        tmp_strstream << ends;
        tmp_string = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);

        return tmp_string;

} // string gstr_map



//#######################################
template <typename T1, typename T2>
ostream& operator<<(ostream &str_o, const map<T1, T2, less<T1> >& map_i)
{
        return str_o << gstr_map (map_i);

} // ostream& operator<<(ostream &str_o, const map<T1>& map_i)


#endif	// huf_service_H


//#######################################################
//################ END OF FILE ##########################
//####################################################### 
------------------- C++ code : END ---------------------- === File #1 of 4 : huf_service.H ======================== ######################################################### === File #2 of 4 : huf_class.H ========================== ------------------- C++ code : BEGIN --------------------
// ==============================================================
//
//  Copyright (c) 1999-2001 by Alex Vinokur.  This work and all works
//  derived from it may be copied and modified without any
//  restrictions other than that a copy of this copyright notice
//  must be included in any copy of this work or any derived work.
//
// ==============================================================

///////////////////////////////////////

#ifndef huf_class_H
#define huf_class_H

///////////////////////////////////////

static char id_huf_class_H[] = "@(#)## n-ary Huffman Template Algorithm ## Author : Alex Vinokur ## "__FILE__;

// ##############################################################
// =============================
//  n-ary Huffman Template Algorithm
//  The algorithm (program) contains the following files :
//  - huf_service.H
//  - huf_class.H
//  - huf_methods.H
//  - huf_main.C
// =============================
//
//  FILE : huf_class.H
//
//  AUTHOR : Alex Vinokur
//
//  DESCRIPTION :
//         Definition of the following template classes :
//         ----------------------------------------------
//         - Cell                         <SYMBOL, WEIGHT>
//         - Node                         <SYMBOL, WEIGHT>
//         - InternalNode                 <SYMBOL, WEIGHT>
//         - TerminalNode                 <SYMBOL, WEIGHT>
//         - BasicHuffmanTree             <SYMBOL, WEIGHT, ARY>
//         - LoadedHuffmanTree            <SYMBOL, WEIGHT, ARY>
//         - DriedHuffmanTree             <WEIGHT, ARY>
//         ----------------------------------------------
//
//         Definition and implementation of the following template classes :
//         ----------------------------------------------
//         - lessNodesCompare             <SYMBOL, WEIGHT>
//         - lessNodesCorrectingCompare01 <SYMBOL, WEIGHT>
//         - lessNodesCorrectingCompare02 <SYMBOL, WEIGHT>
//         - lessCellsCompare             <SYMBOL, WEIGHT>
//         - lessVectorsAlterCompare      <T>
//         ----------------------------------------------
//
//  DATE           VERSION
//  ----           -------
//  Aug-26-1999    NHTA 1.0
//  Jul-05-2001    NHTA 1.1
//  Sep-11-2001    NHTA 1.2
//
// ##############################################################

//======================
#include "huf_service.H"
//======================

//#######################################################
//##### PART : DEFINES & CONSTANTS ######################
//#######################################################

//#define       SHOW_HUFFMAN_PROCESS_STATUS


//#######################################################
//##### PART : DECLARATIONS #############################
//#######################################################

template <typename SYMBOL, typename WEIGHT>
class Cell;

template <typename SYMBOL, typename WEIGHT>
class Node;

template <typename SYMBOL, typename WEIGHT>
class InternalNode ;

template <typename SYMBOL, typename WEIGHT>
class TerminalNode ;

template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
class BasicHuffmanTree;

template <typename SYMBOL, typename WEIGHT, unsigned int ARY = 2>
class LoadedHuffmanTree;

template <typename WEIGHT, unsigned int ARY = 2>
class DriedHuffmanTree;

template <typename SYMBOL, typename WEIGHT>
class lessNodesCompare;

template <typename SYMBOL, typename WEIGHT>
class lessNodesCorrectingCompare01;

template <typename SYMBOL, typename WEIGHT>
class lessNodesCorrectingCompare02;

template <typename SYMBOL, typename WEIGHT>
class lessCellsCompare;

template <typename T1>
class lessVectorsAlterCompare;




//#######################################################
//##### PART : template class Cell ######################
//############ Definition ###############################
//#######################################################

//----------- template class Cell -----------
template <typename SYMBOL, typename WEIGHT>
class Cell
{
template <typename S1, typename W1, unsigned int A1> friend class BasicHuffmanTree;

friend class TerminalNode<SYMBOL, WEIGHT>;
friend class lessCellsCompare<SYMBOL, WEIGHT>;
friend istream& operator>> <SYMBOL, WEIGHT> (istream &str_o, Cell<SYMBOL, WEIGHT>& instance_i);

        private :
                SYMBOL  data_symbol_;
                WEIGHT  data_weight_;
                unsigned int    symbol_original_index_;
                vector<CODE>    symbol_path_;
        protected :

        public :
                Cell () {}
                Cell (
                        const SYMBOL&   data_symbol_i,
                        const WEIGHT&   data_weight_i,
                        unsigned int    symbol_original_index_i = UINT_MAX
                        );
                virtual ~Cell () {}

};




//#######################################################
//##### PART : template class Node ######################
//############ Definition ###############################
//#######################################################

//----------- template class Node -----------
template <typename SYMBOL, typename WEIGHT>
class Node
{
template <typename S1, typename W1, unsigned int A1> friend class BasicHuffmanTree;

friend class InternalNode<SYMBOL, WEIGHT>;
friend class lessNodesCompare<SYMBOL, WEIGHT>;
friend class lessNodesCorrectingCompare01<SYMBOL, WEIGHT>;
friend class lessNodesCorrectingCompare02<SYMBOL, WEIGHT>;
friend ostream& operator<< <SYMBOL, WEIGHT> (ostream &str_o, const Node<SYMBOL, WEIGHT>& instance_i);

typedef map<SYMBOL, WEIGHT, less<SYMBOL> > Node_MAP_SYMBOLS;

        private :
        protected :
                Node_MAP_SYMBOLS        mapSymbols_;
                WEIGHT                  weight_;
                bool                    is_TerminalNode_;
                int                     absorbtion_stage_;
                int                     creation_stage_;

        public :
                Node () {weight_ = WEIGHT (); absorbtion_stage_ = -2; creation_stage_ = -1;}
                virtual ~Node () {}
};




//#######################################################
//##### PART : template class InternalNode ##############
//############ Definition ###############################
//#######################################################

//----------- template class InternalNode -----------
template <typename SYMBOL, typename WEIGHT>
class InternalNode : public Node<SYMBOL, WEIGHT>
{
template <typename S1, typename W1, unsigned int A1> friend class BasicHuffmanTree;
        private :
                vector<Node<SYMBOL, WEIGHT>*>   arc_;
        protected :
                void addNode (Node<SYMBOL, WEIGHT> const *  const ptr2_i);
        public :
                InternalNode () {is_TerminalNode_ = false;}
                ~InternalNode () {}
};




//#######################################################
//##### PART : template class TerminalNode ##############
//############ Definition ###############################
//#######################################################

//----------- template class TerminalNode -----------
template <typename SYMBOL, typename WEIGHT>
class TerminalNode : public Node<SYMBOL, WEIGHT>
{
template <typename S1, typename W1, unsigned int A1> friend class BasicHuffmanTree;
        private :

        protected :
        public :
                TerminalNode () {is_TerminalNode_ = true;}
                TerminalNode (const Cell<SYMBOL, WEIGHT>& cell_i);
                ~TerminalNode () {}
};



//#######################################################
//##### PART : template class less... ###################
//#######################################################

//#######################################################
//----------- template class lessNodesCompare -----------
template <typename SYMBOL, typename WEIGHT>
class lessNodesCompare
{
public:
        bool operator()(
                        const Node<SYMBOL, WEIGHT>* const left_i,
                        const Node<SYMBOL, WEIGHT>* const right_i
                        )
        {
                return (left_i->weight_ < right_i->weight_);
        }
};


//#######################################################
//------- template class lessNodesCorrectingCompare01 -----
template <typename SYMBOL, typename WEIGHT>
class lessNodesCorrectingCompare01
{
public:
        bool operator()(
                        const Node<SYMBOL, WEIGHT>* const left_i,
                        const Node<SYMBOL, WEIGHT>* const right_i
                        )
        {
                return ((left_i->weight_ == right_i->weight_) ? (!(left_i->is_TerminalNode_)) : (left_i->weight_ < right_i->weight_));
        }
};



//#######################################################
//------- template class lessNodesCorrectingCompare02 -----
template <typename SYMBOL, typename WEIGHT>
class lessNodesCorrectingCompare02
{
public:
        bool operator()(
                        const Node<SYMBOL, WEIGHT>* const left_i,
                        const Node<SYMBOL, WEIGHT>* const right_i
                        )
        {
                return ((left_i->is_TerminalNode_ == right_i->is_TerminalNode_) ? (left_i->weight_ < right_i->weight_) : (!(left_i->is_TerminalNode_)));
        }
};


//#######################################################
//----------- template class lessCellsCompare -----------
template <typename SYMBOL, typename WEIGHT>
class lessCellsCompare
{
public:
        bool operator()(
                        const Cell<SYMBOL, WEIGHT>& left_i,
                        const Cell<SYMBOL, WEIGHT>& right_i
                        )
        {

                return (left_i.data_weight_ < right_i.data_weight_);
        }
};




//#######################################################
//----------- template class lessVectorsAlterCompare -----------
template <typename T1>
class lessVectorsAlterCompare
{
public:
        bool operator()(
                        const vector<T1>&       left_i,
                        const vector<T1>&       right_i
                        )
        {
                if (left_i.size () < right_i.size ())
                {
                        return true;
                }

                if (left_i.size () > right_i.size ())
                {
                        return false;
                }

                return (left_i < right_i);
        }
};




//#######################################################
//##### PART : template class BasicHuffmanTree ##########
//############ Definition ###############################
//#######################################################


//#######################################################
//----------- template class BasicHuffmanTree -----------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
class BasicHuffmanTree
{
typedef map<SYMBOL, Cell<SYMBOL, WEIGHT>, less<SYMBOL> > Tree_MAP_SYMBOLS;
typedef map<vector<CODE>, SYMBOL, less<vector<CODE> > > Tree_MAP_HUFFMAN_DECODING;

        private :
                Tree_MAP_SYMBOLS                mapAlphabet_;
                Tree_MAP_HUFFMAN_DECODING       mapHuffmanCodes_;
                InternalNode<SYMBOL, WEIGHT>    rootNode_;
                vector<vector<CODE> >           vectorHuffmanCodes_;


                void    createAllTerminalNodes (
                                const vector<Cell<SYMBOL, WEIGHT> >&    data_vector_i,
                                vector<Node<SYMBOL, WEIGHT>*>&          vectorHuffmanProcess_i
                                );
                void    createInternalNode (
                                vector<Node<SYMBOL, WEIGHT>*>&          vectorHuffmanProcess_i,
                                int                                     cur_stage_i
                                );

                void    createHuffmanTree (
                                vector<Node<SYMBOL, WEIGHT>*>&          vectorHuffmanProcess_i
                                );

                void    doBeautyTreatment (
                                vector<Node<SYMBOL, WEIGHT>*>&          vectorHuffmanProcess_i
                                );


                void    storeHuffmanCodes ();


                bool            encodeOneSymbol (
                                        const SYMBOL&   symbol_i,
                                        vector<CODE>&   path_o)
                                        const;


                bool            decodeOneSymbol (
                                        const vector<CODE>&     encoded_msg_i,
                                        unsigned int&           cur_start_position_io,
                                        unsigned int&           cur_symbol_number_io,
                                        vector<CODE>&           cur_symbol_code_o,
                                        SYMBOL&                 cur_symbol_value_o
                                        ) const;

                bool            decodeOneSymbol (
                                        const vector<CODE>&     encoded_symbol_code_i,
                                        SYMBOL&                 decoded_symbol_value_o
                                        ) const;

                bool            testAllCodes (bool show_i = false) const;

                void            showHuffmanProcessStatus (
                                        vector<Node<SYMBOL, WEIGHT>*>&  vectorHuffmanProcess_i,
                                        int                             cur_stage_i = 0,
                                        const string&                   msg_i = string ()
                                        ) const;

                static void     print_show_title_S (
                                        const string&   spaces_offset_i,
                                        unsigned int    setw_symbol_i,
                                        const string&   symbol_title_i,
                                        unsigned int    setw_weight_i,
                                        const string&   weight_title_i,
                                        const string&   code_title_i
                                        );

                static void     print_show_line_S (
                                        const string&   spaces_offset_i,
                                        unsigned int    setw_symbol_i,
                                        const SYMBOL&   symbol_i,
                                        unsigned int    setw_weight_i,
                                        const WEIGHT&   weight_i,
                                        const vector<CODE>&     path_i
                                        );


                bool            knowSymbolWeight (
                                        const SYMBOL&   symbol_i,
                                        WEIGHT&         weight_o
                                        ) const;

                bool            knowCodeSymbol (
                                        const vector<CODE>&     path_i,
                                        SYMBOL&                 symbol_o
                                        ) const;

                WEIGHT          getWeightsSum () const;

                WEIGHT          getAverageWeight () const
                {
                        return (getWeightsSum ()/getAlphabetSize ());
                }

                unsigned int    getCodeAry () const {return ARY;}

                unsigned int    getLongestSymbolSize () const;

                unsigned int    getAlphabetSize () const
                {
                        return vectorHuffmanCodes_.size ();
                }

                unsigned int    getShortestCodeSize () const
                {
                        return vectorHuffmanCodes_[0].size ();
                }

                unsigned int    getLongestCodeSize () const
                {
                        return vectorHuffmanCodes_[vectorHuffmanCodes_.size () - 1].size ();
                }

                unsigned int    getCodeSizesSum () const;

                float           getAverageCodeSize () const
                {
                        return (static_cast<float>(getCodeSizesSum ())/static_cast<float>(getAlphabetSize ()));
                }

                WEIGHT          getAverageWeightedCodeSize () const
                {
                        return (getWeightedCodeSizesSum ())/(getAlphabetSize ());
                }

                WEIGHT          getWeightedCodeSizesSum () const;

        protected :
                void    doBasicHuffmanTree (
                                const vector<Cell<SYMBOL, WEIGHT> >& data_vector_i
                                );

                BasicHuffmanTree () {}

                BasicHuffmanTree (
                        const vector<Cell<SYMBOL, WEIGHT> >& data_vector_i
                        );

                BasicHuffmanTree (const string& data_file_name_i);

                virtual ~BasicHuffmanTree () {}

        public :
                bool            encodeMsg (
                                        const vector<SYMBOL>&   source_msg_i,
                                        vector<CODE>&           encoded_msg_o)
                                        const;

                bool            encodeMsg (
                                        const basic_string<SYMBOL>&     source_msg_i,
                                        string&                         encoded_msg_o)
                                        const;

                bool            decodeMsg (
                                        const vector<CODE>&     encoded_msg_i,
                                        vector<SYMBOL>&         decoded_msg_o
                                        ) const;

                bool            decodeMsg (
                                        const string&                   encoded_msg_i,
                                        basic_string<SYMBOL>&           decoded_msg_o
                                        ) const;


                void            showAll (const string& msg_i = string ()) const;
};





//#######################################################
//##### PART : template class LoadedHuffmanTree #########
//############ Definition ###############################
//#######################################################

//----------- template class LoadedHuffmanTree -----------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
class LoadedHuffmanTree : public BasicHuffmanTree<SYMBOL, WEIGHT, ARY>
{

        public :
                LoadedHuffmanTree () : BasicHuffmanTree<SYMBOL, WEIGHT, ARY> () {}

                LoadedHuffmanTree (
                        const vector<Cell<SYMBOL, WEIGHT> >& data_vector_i
                        )
                        :
                        BasicHuffmanTree<SYMBOL, WEIGHT, ARY> (data_vector_i) {}

                LoadedHuffmanTree (const string& data_file_name_i)
                : BasicHuffmanTree<SYMBOL, WEIGHT, ARY> (data_file_name_i) {}

                ~LoadedHuffmanTree () {}
};





//#######################################################
//##### PART : template class DriedHuffmanTree ##########
//############ Definition ###############################
//#######################################################

//----------- template class DriedHuffmanTree -----------
template <typename WEIGHT, unsigned int ARY>
class DriedHuffmanTree : public BasicHuffmanTree<string, WEIGHT, ARY>
{
        private :

                void    doDriedHuffmanTree (
                                const vector<WEIGHT>& weight_vector_i
                                );
        protected :
        public :

                DriedHuffmanTree (
                                const vector<WEIGHT>& weight_vector_i
                                );
                DriedHuffmanTree (const string& weights_file_name_i);

                ~DriedHuffmanTree () {}
};


#endif	// huf_class_H

//#######################################################
//################ END OF FILE ##########################
//#######################################################
------------------- C++ code : END ---------------------- === File #2 of 4 : huf_class.H ========================== ######################################################### === File #3 of 4 : huf_methods.H ======================== ------------------- C++ code : BEGIN --------------------
// ==============================================================
//
//  Copyright (c) 1999-2001 by Alex Vinokur.  This work and all works
//  derived from it may be copied and modified without any
//  restrictions other than that a copy of this copyright notice
//  must be included in any copy of this work or any derived work.
//
// ==============================================================

///////////////////////////////////////

#ifndef huf_methods_H
#define huf_methods_H

///////////////////////////////////////

static char id_huf_methods_H[] = "@(#)## n-ary Huffman Template Algorithm ## Author : Alex Vinokur ## "__FILE__;

// ##############################################################
// =============================
//  n-ary Huffman Template Algorithm
//  The algorithm (program) contains the following files :
//  - huf_service.H
//  - huf_class.H
//  - huf_methods.H
//  - huf_main.C
// =============================
//
//  FILE : huf_methods.H
//
//  AUTHOR : Alex Vinokur
//
//  DESCRIPTION :
//         Implementation of methods of the following template classes :
//         ----------------------------------------------
//         - Cell                         <SYMBOL, WEIGHT>
//         - Node                         <SYMBOL, WEIGHT>
//         - InternalNode                 <SYMBOL, WEIGHT>
//         - TerminalNode                 <SYMBOL, WEIGHT>
//         - BasicHuffmanTree             <SYMBOL, WEIGHT, ARY>
//         - DriedHuffmanTree             <WEIGHT, ARY>
//         ----------------------------------------------
//	   Note. The following class has no its own methods :
//         - LoadedHuffmanTree            <SYMBOL, WEIGHT, ARY>
//         ----------------------------------------------
//
//  DATE           VERSION
//  ----           -------
//  Aug-26-1999    NHTA 1.0
//  Jul-05-2001    NHTA 1.1
//  Sep-11-2001    NHTA 1.2
//
// ##############################################################



//=====================
#include "huf_class.H"
//=====================




//#######################################################
//##### PART : template class Cell ######################
//############ Methods ##################################
//#######################################################

//-----------------------
// Constructor
template <typename SYMBOL, typename WEIGHT>
Cell<SYMBOL, WEIGHT>::Cell (
                        const SYMBOL&   data_symbol_i,
                        const WEIGHT&   data_weight_i,
                        unsigned int    symbol_original_index_i
                        )
{
        data_symbol_            = data_symbol_i;
        data_weight_            = data_weight_i;
        symbol_original_index_  = symbol_original_index_i;
} // Cell<SYMBOL, WEIGHT>::Cell (


//-----------------------
template <typename SYMBOL, typename WEIGHT>
istream& operator>>(istream &stream_o, Cell<SYMBOL, WEIGHT>& instance_i)
{
        stream_o >> instance_i.data_symbol_ >> instance_i.data_weight_;
        return stream_o;
}





//#######################################################
//##### PART : template class Node ######################
//############ Methods ##################################
//#######################################################

//-----------------------
template <typename SYMBOL, typename WEIGHT>
ostream& operator<<(ostream &str_o, const Node<SYMBOL, WEIGHT>& instance_i)
{
const string shift_CNS = "\t---> ";
        return str_o << endl
                     << shift_CNS
                     << "weight_ = "
                     << instance_i.weight_
                     << gstr_map (instance_i.mapSymbols_, shift_CNS);
}





//#######################################################
//##### PART : template class InternalNode ##############
//############ Methods ##################################
//#######################################################

//-----------------------
template <typename SYMBOL, typename WEIGHT>
void InternalNode<SYMBOL, WEIGHT>::addNode(Node<SYMBOL, WEIGHT> const * const ptr2_i)
{
SYMBOL  cur_symbol;
WEIGHT  cur_weight;

Node_MAP_SYMBOLS::const_iterator                const_iterSymbols;


        ASSERT (!(ptr2_i == NULL));

        //=============== ptr2 =====================
        weight_ += ptr2_i->weight_;

        for (const_iterSymbols = ptr2_i->mapSymbols_.begin();
             !(const_iterSymbols == ptr2_i->mapSymbols_.end());
             const_iterSymbols++
             )
        {
                cur_symbol = (*const_iterSymbols).first;
                cur_weight = (*const_iterSymbols).second;
                //==========================================
                ASSERT (!mapSymbols_.count (cur_symbol));
                //==========================================
                if (!((mapSymbols_.insert (Node_MAP_SYMBOLS::value_type (cur_symbol, cur_weight))).second))
                {
                        ASSERT (0);
                }
                //==========================================
        }


} // void InternalNode<SYMBOL, WEIGHT>::addNode(





//#######################################################
//##### PART : template class TerminalNode ##############
//############ Methods ##################################
//#######################################################

//-----------------------
// Constructor
template <typename SYMBOL, typename WEIGHT>
TerminalNode<SYMBOL, WEIGHT>::TerminalNode (const Cell<SYMBOL, WEIGHT>& cell_i)
{
        //==========================================
        is_TerminalNode_ = true;
        //==========================================
        ASSERT (!mapSymbols_.count (cell_i.data_symbol_));

        weight_ = cell_i.data_weight_;
        if (!((mapSymbols_.insert (Node_MAP_SYMBOLS::value_type (cell_i.data_symbol_, weight_))).second))
        {
                ASSERT (0);
        }

} // TerminalNode<SYMBOL, WEIGHT>::TerminalNode





//#######################################################
//##### PART : template class BasicHuffmanTree ##########
//############ Methods ##################################
//#######################################################

//-----------------------
// Constructor-1
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::BasicHuffmanTree (
                        const vector<Cell<SYMBOL, WEIGHT> >& data_vector_i
                        )
{
        doBasicHuffmanTree (data_vector_i);

} // BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::BasicHuffmanTree ()


//-----------------------
// Constructor-2
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::BasicHuffmanTree (const string& data_file_name_i)
{
vector<Cell<SYMBOL, WEIGHT> >   data_vector;

ifstream fin (data_file_name_i.c_str ());

        if (!fin)
        {
                FATAL_MSG ("Cannot open file <"
                            << data_file_name_i
                            << "> for reading"
                            << endl
                            << FATAL_SHIFT
                            << "The file must contain data to be Huffman-coded"
                            );
        }

        copy(istream_iterator<Cell<SYMBOL, WEIGHT> >(fin),
             istream_iterator<Cell<SYMBOL, WEIGHT> >(),
             back_inserter(data_vector));

        doBasicHuffmanTree (data_vector);
} // BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::BasicHuffmanTree ()



//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::doBasicHuffmanTree (
                        const vector<Cell<SYMBOL, WEIGHT> >& data_vector_i
                        )
{
        if (!(ARY >= 2))
        {
                FATAL_MSG ("Illegal ARY - "
                            << ARY
                            << " (Must be >= 2)"
                            );
        }

        switch (data_vector_i.size ())
        {
                case 0 :
                        FATAL_MSG ("Empty alphabet"
                                    << endl
                                    << FATAL_SHIFT
                                    << "Alphabet size must be >= 2"
                                    );
                        break;

                case 1 :
                        FATAL_MSG ("Alphabet size = "
                                    << data_vector_i.size ()
                                    << endl
                                    << FATAL_SHIFT
                                    << "Alphabet size must be >= 2"
                                    );
                        break;

                default :
                        break;
        } // switch


        ASSERT (ARY >= 2);
        if (!((data_vector_i.size () - 1)%(ARY - 1) == 0))
        {
                FATAL_MSG ("Illegal alphabet size (N = "
                            << data_vector_i.size ()
                            << ") for "
                            << ARY
                            << "-ary tree."
                            << endl
                            << FATAL_SHIFT
                            << "N must satisfy the following condition : (N - 1) mod ("
                            << (ARY - 1)
                            << ") = 0"
                            << endl
                            << FATAL_SHIFT
                            << "In reality "
                            << (data_vector_i.size () - 1)
                            << " mod ("
                            << (ARY - 1)
                            << ")"
                            << " = "
                            << ((data_vector_i.size () - 1)%(ARY - 1))
                            );
        }

        ASSERT (data_vector_i.size () > 1);

        ASSERT ((data_vector_i.size () - 1)%(ARY - 1) == 0);

        //=================
vector<Node<SYMBOL, WEIGHT>*>           vectorHuffmanProcess;

        createAllTerminalNodes (data_vector_i, vectorHuffmanProcess);
        createHuffmanTree (vectorHuffmanProcess);
        storeHuffmanCodes ();

        //=================
InternalNode<SYMBOL, WEIGHT>*           ptrRootNode;
        ASSERT (vectorHuffmanProcess.size () == 1);
        ptrRootNode = dynamic_cast<InternalNode<SYMBOL, WEIGHT>*> (vectorHuffmanProcess [0]);
        ASSERT (!(ptrRootNode == NULL));
        //=================
        rootNode_ = *ptrRootNode;
        //=================
        delete (vectorHuffmanProcess [0]);
        //=================
        ASSERT (testAllCodes ());
        //=================
        ASSERT (mapAlphabet_.size () == mapHuffmanCodes_.size ());
        ASSERT (mapAlphabet_.size () == vectorHuffmanCodes_.size ());
        ASSERT (mapHuffmanCodes_.size () == vectorHuffmanCodes_.size ());
        //=================
} // BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::doBasicHuffmanTree ()




//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::createInternalNode (
                                vector<Node<SYMBOL, WEIGHT>*>&  vectorHuffmanProcess_i,
                                int                             cur_stage_i
                                )
{
unsigned int    cur_arc;
map<SYMBOL, WEIGHT, less<SYMBOL> >::iterator    iterSymbols;
InternalNode<SYMBOL, WEIGHT>*   newPtrInternalNode = new InternalNode<SYMBOL, WEIGHT> ();

        ASSERT (!(newPtrInternalNode == NULL));

Node<SYMBOL, WEIGHT>*   front_element;
        ASSERT (newPtrInternalNode->arc_.empty ());
        for (cur_arc = 0; cur_arc < ARY; cur_arc++)
        {
                front_element = vectorHuffmanProcess_i.front ();
                front_element->absorbtion_stage_ = cur_stage_i;
                newPtrInternalNode->addNode (front_element);

                for (iterSymbols = front_element->mapSymbols_.begin();
                     !(iterSymbols == front_element->mapSymbols_.end());
                     iterSymbols++
                     )
                {
                        ASSERT (mapAlphabet_.count ((*iterSymbols).first));
                        vector<CODE>& alias_symbol_path = mapAlphabet_ [(*iterSymbols).first].symbol_path_;
                        ASSERT (newPtrInternalNode->arc_.size () == cur_arc);
                        alias_symbol_path.insert (alias_symbol_path.begin (), newPtrInternalNode->arc_.size ());
                }
                //=====================================
                vectorHuffmanProcess_i.erase (vectorHuffmanProcess_i.begin ());
                newPtrInternalNode->creation_stage_ = cur_stage_i;
                newPtrInternalNode->arc_.push_back (front_element);
                //==========================================
        }
        ASSERT (newPtrInternalNode->arc_.size () == ARY);

        //==========================================
        vectorHuffmanProcess_i.push_back (newPtrInternalNode);
        stable_sort (vectorHuffmanProcess_i.begin (), vectorHuffmanProcess_i.end (), lessNodesCompare<SYMBOL, WEIGHT> ());
        //==========================================
        ASSERT ((((ARY - 1) * cur_stage_i) + vectorHuffmanProcess_i.size ()) == mapAlphabet_.size ());

        //---------------------

} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::createInternalNode


//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::createHuffmanTree (
                                vector<Node<SYMBOL, WEIGHT>*>&  vectorHuffmanProcess_i
                                )
{
#ifdef SHOW_HUFFMAN_PROCESS_STATUS
        showHuffmanProcessStatus (vectorHuffmanProcess_i);
#endif

int cur_stage = 0;
        while (vectorHuffmanProcess_i.size () > 1)
        {
                cur_stage++;
                createInternalNode (vectorHuffmanProcess_i, cur_stage);
                doBeautyTreatment (vectorHuffmanProcess_i);
#ifdef SHOW_HUFFMAN_PROCESS_STATUS
                showHuffmanProcessStatus (vectorHuffmanProcess_i, cur_stage);
#endif
        }
        ASSERT (vectorHuffmanProcess_i.size () == 1);
        ASSERT (!(vectorHuffmanProcess_i [0]->is_TerminalNode_));

} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::createHuffmanTree ()



//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::doBeautyTreatment (
                                vector<Node<SYMBOL, WEIGHT>*>&  vectorHuffmanProcess_i
                                )
{
        ASSERT (!(vectorHuffmanProcess_i.empty ()));
        if (vectorHuffmanProcess_i.size () == 1)
        {
                return;
        }
        stable_sort (vectorHuffmanProcess_i.begin (), vectorHuffmanProcess_i.end (), lessNodesCorrectingCompare01<SYMBOL, WEIGHT> ());
        stable_sort (vectorHuffmanProcess_i.begin (), vectorHuffmanProcess_i.begin () + ARY, lessNodesCorrectingCompare02<SYMBOL, WEIGHT> ());

} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::doBeautyTreatment ()




//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::createAllTerminalNodes (
                        const vector<Cell<SYMBOL, WEIGHT> >&    data_vector_i,
                        vector<Node<SYMBOL, WEIGHT>*>&  vectorHuffmanProcess_i
                        )
{
unsigned int    cur_index;
SYMBOL          cur_symbol;
WEIGHT          cur_weight;

        for (cur_index = 0; cur_index < data_vector_i.size (); cur_index++)
        {
                //==========================================
                cur_symbol = data_vector_i [cur_index].data_symbol_;
                cur_weight = data_vector_i [cur_index].data_weight_;
                //==========================================
                if (mapAlphabet_.count(cur_symbol))
                {
                        FATAL_MSG ("Symbol <"
                                    << cur_symbol
                                    << "> occurs more than one time"
                                    << endl
                                    << FATAL_SHIFT
                                    << "See symbol ["
                                    << cur_index
                                    << "]"
                                    << " and "
                                    << "symbol ["
                                    << (*(mapAlphabet_.find (cur_symbol))).second.symbol_original_index_
                                    << "]"
                                    << endl
                                    << FATAL_SHIFT
                                    << "Note! First symbol is symbol [0]"
                                    );
                }
                //==========================================
                if (!((mapAlphabet_.insert (Tree_MAP_SYMBOLS::value_type (cur_symbol, Cell<SYMBOL, WEIGHT> (cur_symbol, cur_weight, cur_index)))).second))
                {
                        ASSERT (0);
                }
        } // for (unsigned int i = 0; i < data_vector_i.size (); i++)

        //=====================================
TerminalNode<SYMBOL, WEIGHT>*   newPtrTerminalNode;
Tree_MAP_SYMBOLS::iterator      iterAlphabet;
        for (iterAlphabet = mapAlphabet_.begin();
             !(iterAlphabet == mapAlphabet_.end());
             iterAlphabet++
             )
        {
                newPtrTerminalNode = new TerminalNode<SYMBOL, WEIGHT> ((*iterAlphabet).second);
                ASSERT (!(newPtrTerminalNode == NULL));
                newPtrTerminalNode->creation_stage_ = 0;

                vectorHuffmanProcess_i.push_back (newPtrTerminalNode);
        }

        stable_sort (vectorHuffmanProcess_i.begin (), vectorHuffmanProcess_i.end (), lessNodesCompare<SYMBOL, WEIGHT> ());
} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::createAllTerminalNodes




//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::storeHuffmanCodes ()
{

Tree_MAP_SYMBOLS::iterator                      iterAlphabet;

        //=====================================
        for (iterAlphabet = mapAlphabet_.begin();
             !(iterAlphabet == mapAlphabet_.end());
             iterAlphabet++
             )
        {
                ASSERT (!mapHuffmanCodes_.count ((*iterAlphabet).second.symbol_path_));
                if (!((mapHuffmanCodes_.insert (Tree_MAP_HUFFMAN_DECODING::value_type ((*iterAlphabet).second.symbol_path_, (*iterAlphabet).first))).second))
                {
                        ASSERT (0);
                }

                vectorHuffmanCodes_.push_back ((*iterAlphabet).second.symbol_path_);

        }

        stable_sort (vectorHuffmanCodes_.begin (), vectorHuffmanCodes_.end (), lessVectorsAlterCompare<CODE> ());


} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::storeHuffmanCodes ()


//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
unsigned int BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getCodeSizesSum () const
{
unsigned int    ret_intValue = 0;
        for (unsigned int cur_index = 0; cur_index < vectorHuffmanCodes_.size (); cur_index++)
        {
                ret_intValue += vectorHuffmanCodes_[cur_index].size ();
        }
        return ret_intValue;
} // unsigned int BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getCodeSizesSum () const


//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getWeightsSum () const
{
Tree_MAP_SYMBOLS::const_iterator        const_iterAlphabet;
WEIGHT ret_WEIGHT_Value;
        //=====================================
        ret_WEIGHT_Value = WEIGHT ();
        for (const_iterAlphabet = mapAlphabet_.begin();
             !(const_iterAlphabet == mapAlphabet_.end());
             const_iterAlphabet++
             )
        {
                ret_WEIGHT_Value += (*const_iterAlphabet).second.data_weight_;
        }

        return ret_WEIGHT_Value;

} // WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getWeightsSum () const


//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
unsigned int BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getLongestSymbolSize () const
{
Tree_MAP_SYMBOLS::const_iterator        const_iterAlphabet;

        //=====================================
unsigned int ret_intValue = 0;

        for (const_iterAlphabet = mapAlphabet_.begin();
             !(const_iterAlphabet == mapAlphabet_.end());
             const_iterAlphabet++
             )
        {
                strstream       tmp_strstream;
                tmp_strstream << (*const_iterAlphabet).first;
                tmp_strstream << ends;
                ret_intValue = MAX_VALUE (ret_intValue, string (tmp_strstream.str()).size ());
                tmp_strstream.rdbuf()->freeze (0);
        }

        //=====================================
        return ret_intValue;

} // WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getLongestSymbolSize () const




//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getWeightedCodeSizesSum () const
{
Tree_MAP_SYMBOLS::const_iterator        const_iterAlphabet;
WEIGHT ret_WEIGHT_Value;
        //=====================================
        ret_WEIGHT_Value = WEIGHT ();
        for (const_iterAlphabet = mapAlphabet_.begin();
             !(const_iterAlphabet == mapAlphabet_.end());
             const_iterAlphabet++
             )
        {
                ret_WEIGHT_Value += ((*const_iterAlphabet).second.data_weight_ * (*const_iterAlphabet).second.symbol_path_.size ());
        }
        //=====================================
        return ret_WEIGHT_Value;
} // WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::getWeightedCodeSizesSum () const


//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::encodeOneSymbol (const SYMBOL& symbol_i, vector<CODE>& path_o) const
{
        if (!mapAlphabet_.count (symbol_i))
        {
                ERROR_MSG ("Symbol <"
                           << symbol_i
                           << "> is out of Alphabet"
                           );
                showAll ();
                return false;

        }
        path_o = (*(mapAlphabet_.find (symbol_i))).second.symbol_path_;

        //=====================================
        return true;

} // WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::encodeOneSymbol () const


//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::knowSymbolWeight (const SYMBOL& symbol_i, WEIGHT& weight_o) const
{
        if (!mapAlphabet_.count (symbol_i))
        {
                ERROR_MSG ("Symbol <"
                           << symbol_i
                           << "> is out of Alphabet"
                           );
                showAll ();
                return false;

        }
        weight_o = (*(mapAlphabet_.find (symbol_i))).second.data_weight_;

        //=====================================
        return true;

} // WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::knowSymbolWeight () const




//-----------------------
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::knowCodeSymbol (const vector<CODE>& path_i, SYMBOL& symbol_o) const
{
        if (!mapHuffmanCodes_.count (path_i))
        {
                ERROR_MSG ("Code <"
                           << gstr_path<ARY> (path_i)
                           << "> is out of Huffman Codes for this Alphabet"
                           );
                showAll ();
                return false;

        }

        symbol_o = (*(mapHuffmanCodes_.find (path_i))).second;

        //=====================================
        return true;

} // WEIGHT BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::knowCodeSymbol () const




//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::showAll (const string& msg_i) const
{

        cout << endl;
        cout << "########### showAll (BEGIN) ###########" << endl;
        if (!msg_i.empty ())
        {
                cout << "\t" << "===== " << msg_i << " =====" << endl;
                cout << endl;
        }

        cout << endl;
        cout << "\t" << "-> This is ";
        switch (ARY)
        {
                case 1 :
                        ASSERT (ARY > 1);
                        break;

                case 2 :
                        cout << "Binary";
                        break;

                case 3 :
                        cout << "Ternary";
                        break;

                default :
                        cout << ARY << "-ary";
                        break;
        }
        cout << " Huffman Coding <-" << endl;

        cout << "\t" << "Alphabet size \t\t= " << getAlphabetSize () << endl;
        cout << "\t" << "Shortest code size \t= " << getShortestCodeSize () << endl;
        cout << "\t" << "Longest code size \t= " << getLongestCodeSize () << endl;
        cout << endl;
        cout << "\t" << "Weights sum \t\t= " << getWeightsSum () << endl;
        cout << "\t" << "Average weight \t\t= " << getAverageWeight () << endl;
        cout << endl;
        cout << "\t" << "Code-sizes sum \t\t= " << getCodeSizesSum () << endl;
        cout << "\t" << "Average code-size \t= " << getAverageCodeSize () << endl;
        cout << endl;
        cout << "\t" << "Weighted code-sizes sum = " << getWeightedCodeSizesSum () << endl;
        cout << "\t" << "Ave. weighted code-size = " << getAverageWeightedCodeSize () << endl;
        cout << endl;
        cout << endl;



        //==================================
Tree_MAP_SYMBOLS::const_iterator                const_iterAlphabet;
Tree_MAP_HUFFMAN_DECODING::const_iterator       const_iterHuffmanCodes;
vector<CODE>                            cur_path;
WEIGHT                                  cur_weight;
SYMBOL                                  cur_symbol;
const string                            spaces_offset_CNS = "   ";
const string                            weight_title_CNS = "Weight";
const string                            symbol_title_CNS = "Symbol";
const string                            code_title_CNS = "Code";
const int                               setw_weight_CNS = 12;
const int                               setw_symbol_CNS = MAX_VALUE (symbol_title_CNS.size (), getLongestSymbolSize ());

        cout << endl;
        cout << endl;
        cout << "\t======================= " << endl;
        cout << "\tSymbols and their codes" << endl;
        cout << "\t -> Sorted by Symbol" << endl;
        cout << "\t======================= " << endl;
        print_show_title_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        symbol_title_CNS,
                        setw_weight_CNS,
                        weight_title_CNS,
                        code_title_CNS
                        );

        //=====================================
        for (const_iterAlphabet = mapAlphabet_.begin();
             !(const_iterAlphabet == mapAlphabet_.end());
             const_iterAlphabet++
             )
        {
                if (!encodeOneSymbol ((*const_iterAlphabet).first, cur_path))
                {
                        ASSERT (0);
                }
                if (!knowSymbolWeight ((*const_iterAlphabet).first, cur_weight))
                {
                        ASSERT (0);
                }

                print_show_line_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        (*const_iterAlphabet).first,
                        setw_weight_CNS,
                        cur_weight,
                        cur_path
                        );

        } // for (const_iterAlphabet = mapAlphabet_.begin() ...
        //=====================================

        cout << endl;
        cout << endl;
        cout << "\t=========================" << endl;
        cout << "\tCodes and their symbols" << endl;
        cout << "\t -> Lexico-Sorted by Code" << endl;
        cout << "\t=========================" << endl;
        print_show_title_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        symbol_title_CNS,
                        setw_weight_CNS,
                        weight_title_CNS,
                        code_title_CNS
                        );

        //=====================================
        for (const_iterHuffmanCodes = mapHuffmanCodes_.begin();
             !(const_iterHuffmanCodes == mapHuffmanCodes_.end());
             const_iterHuffmanCodes++
             )
        {
                if (!knowCodeSymbol ((*const_iterHuffmanCodes).first, cur_symbol))
                {
                        ASSERT (0);
                }
                if (!knowSymbolWeight (cur_symbol, cur_weight))
                {
                        ASSERT (0);
                }


                print_show_line_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        cur_symbol,
                        setw_weight_CNS,
                        cur_weight,
                        (*const_iterHuffmanCodes).first
                        );

        } // for (const_iterHuffmanCodes = mapHuffmanCodes_.begin() ...
        //=====================================


        cout << endl;
        cout << endl;
        cout << "\t=======================" << endl;
        cout << "\tCodes and their symbols" << endl;
        cout << "\t -> Sorted by Code Size" << endl;
        cout << "\t=======================" << endl;
        print_show_title_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        symbol_title_CNS,
                        setw_weight_CNS,
                        weight_title_CNS,
                        code_title_CNS
                        );

        //=====================================
unsigned int    the_index;
        for (the_index = 0; the_index < vectorHuffmanCodes_.size (); the_index++)
        {
                if (!knowCodeSymbol (vectorHuffmanCodes_ [the_index], cur_symbol))
                {
                        ASSERT (0);
                }
                if (!knowSymbolWeight (cur_symbol, cur_weight))
                {
                        ASSERT (0);
                }

                print_show_line_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        cur_symbol,
                        setw_weight_CNS,
                        cur_weight,
                        vectorHuffmanCodes_ [the_index]
                        );
        } // for (const_iterHuffmanCodes = mapHuffmanCodes_.begin() ...
        //=====================================



        cout << endl;
        cout << endl;
        cout << "\t=======================" << endl;
        cout << "\tCodes and their symbols" << endl;
        cout << "\t -> Sorted by Weight" << endl;
        cout << "\t=======================" << endl;
        print_show_title_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        symbol_title_CNS,
                        setw_weight_CNS,
                        weight_title_CNS,
                        code_title_CNS
                        );

vector <Cell<SYMBOL, WEIGHT> >  tmp_vectorCell;
        for (const_iterAlphabet = mapAlphabet_.begin();
             !(const_iterAlphabet == mapAlphabet_.end());
             const_iterAlphabet++
             )
        {
                tmp_vectorCell.push_back ((*const_iterAlphabet).second);
        }
        stable_sort (tmp_vectorCell.begin (), tmp_vectorCell.end (), lessCellsCompare<SYMBOL, WEIGHT> ());


        for (the_index = 0; the_index < tmp_vectorCell.size (); the_index++)
        {
                cur_symbol = tmp_vectorCell [the_index].data_symbol_;
                if (!knowSymbolWeight (cur_symbol, cur_weight))
                {
                        ASSERT (0);
                }
                if (!encodeOneSymbol (cur_symbol, cur_path))
                {
                        ASSERT (0);
                }

                print_show_line_S (
                        spaces_offset_CNS,
                        setw_symbol_CNS,
                        cur_symbol,
                        setw_weight_CNS,
                        cur_weight,
                        cur_path
                        );
        } // for (const_iterHuffmanCodes = mapHuffmanCodes_.begin() ...
        //=====================================


        cout << endl;
        cout << "########### showAll (END) #############" << endl;
        cout << endl;

} // void showAll


//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::showHuffmanProcessStatus (
                        vector<Node<SYMBOL, WEIGHT>*>&  vectorHuffmanProcess_i,
                        int                             cur_stage_i,
                        const string&                   msg_i
                        ) const
{
unsigned int    cur_index;

        cout << endl;
        cout << "########### showHuffmanProcessStatus (BEGIN) ###########" << endl;
        if (!msg_i.empty ())
        {
                cout << "\t" << "===== " << msg_i << " =====" << endl;
                cout << endl;
        }
        cout << endl;
        cout << "Process StageNo    = " << cur_stage_i << endl;
        cout << "ProcessVector Size = " << vectorHuffmanProcess_i.size () << endl;
        cout << endl;

string                  tmp_string;
const unsigned int      setw_weight_CNS = 12;
Node<SYMBOL, WEIGHT>::Node_MAP_SYMBOLS::const_iterator  const_iterSymbols;
const string            linedel_CNS = "--------------------------------------------------";
        for (cur_index = 0; cur_index < vectorHuffmanProcess_i.size (); cur_index++)
        {
                if ((cur_index == 0) || (cur_index == ARY))
                {
                        cout << linedel_CNS << endl;
                }
                //---------------------------------------


                if (vectorHuffmanProcess_i [cur_index]->is_TerminalNode_)
                {
                        tmp_string = " " + to_str (vectorHuffmanProcess_i [cur_index]->weight_) + " ";
                }
                else
                {
                        tmp_string = "[" + to_str (vectorHuffmanProcess_i [cur_index]->weight_) + "]";
                }

                cout.setf (ios::right, ios::adjustfield);
                cout << ""
                     << setw (5)
                     << (cur_index + 1)
                     << ((cur_stage_i == vectorHuffmanProcess_i [cur_index]->creation_stage_) ? "*" : " ")
                     << " -> "
                     << setw (setw_weight_CNS + 2)
                     << tmp_string.c_str ();

                if (!(vectorHuffmanProcess_i [cur_index]->is_TerminalNode_))
                {
                        for (const_iterSymbols = vectorHuffmanProcess_i [cur_index]->mapSymbols_.begin();
                             !(const_iterSymbols == vectorHuffmanProcess_i [cur_index]->mapSymbols_.end());
                             const_iterSymbols++
                             )
                        {
                                cout << endl;
                                cout << "\t";
                                cout << "\t";
                                cout << "\t";
                                cout << ""
                                     << setw (setw_weight_CNS)
                                     << (*const_iterSymbols).second
                                     << ", "
                                     << setw (getLongestSymbolSize ())
                                     << (*const_iterSymbols).first
                                     << ", ";
                                if (vectorHuffmanProcess_i.size () > 1)
                                {
                                        cout << "...";
                                }
                                cout <<(*(mapAlphabet_.find ((*const_iterSymbols).first))).second.symbol_path_
                                     << "  ";
                        } // for (const_iterSymbols = ...
                } // if (!(vectorHuffmanProcess_i [cur_index]->is_TerminalNode_))
                else
                {
                        ASSERT (vectorHuffmanProcess_i [cur_index]->mapSymbols_.size () == 1);
                        const_iterSymbols = vectorHuffmanProcess_i [cur_index]->mapSymbols_.begin();
                        ASSERT ((*const_iterSymbols).second == vectorHuffmanProcess_i [cur_index]->weight_);
                        cout << ", " << ((*const_iterSymbols).first);
                }

                cout << endl;
        }
        cout << endl;

        cout << "########### showHuffmanProcessStatus (END) #############" << endl;
        cout << endl;

} // void showHuffmanProcessStatus



//#######################################
// static
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::print_show_line_S (
                                        const string&   spaces_offset_i,
                                        unsigned int    setw_symbol_i,
                                        const SYMBOL&   symbol_i,
                                        unsigned int    setw_weight_i,
                                        const WEIGHT&   weight_i,
                                        const vector<CODE>&     path_i
                                        )
{
string  tmp_string;

strstream       tmp_strstream_weight;
        tmp_strstream_weight << weight_i;
        tmp_strstream_weight << ends;
        tmp_string = tmp_strstream_weight.str();
        tmp_strstream_weight.rdbuf()->freeze (0);
        cout.setf (ios::right, ios::adjustfield);
        cout << setw (setw_weight_i)
             << tmp_string.c_str ();


strstream       tmp_strstream_symbol;
        tmp_strstream_symbol << symbol_i;
        tmp_strstream_symbol << ends;
        tmp_string = tmp_strstream_symbol.str();
        tmp_strstream_symbol.rdbuf()->freeze (0);
        cout.setf (ios::left, ios::adjustfield);
        cout << spaces_offset_i
             << setw (setw_symbol_i)
             << tmp_string.c_str ();

        cout.setf (ios::left, ios::adjustfield);
        cout << spaces_offset_i
             << gstr_path<ARY> (path_i);

        cout << endl;
} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::print_show_line_S



//#######################################
// static
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::print_show_title_S (
                                        const string&   spaces_offset_i,
                                        unsigned int    setw_symbol_i,
                                        const string&   symbol_title_i,
                                        unsigned int    setw_weight_i,
                                        const string&   weight_title_i,
                                        const string&   code_title_i
                                        )
{
        cout.setf (ios::right, ios::adjustfield);
        cout << setw (setw_weight_i)
             << weight_title_i.c_str ();

        cout.setf (ios::left, ios::adjustfield);
        cout << spaces_offset_i
             << setw (setw_symbol_i)
             << symbol_title_i.c_str ();

        cout.setf (ios::left, ios::adjustfield);
        cout << spaces_offset_i
             << code_title_i.c_str ();

        cout << endl;

const char      the_char = '-';
unsigned int    cur_index;
        cout.setf (ios::right, ios::adjustfield);
        cout << setw (setw_weight_i - weight_title_i.size ()) << string ().c_str ();
        for (cur_index = 0; cur_index < weight_title_i.size (); cur_index++)
        {
                cout << the_char;
        }

        cout.setf (ios::left, ios::adjustfield);
        cout << spaces_offset_i;
        for (cur_index = 0; cur_index < symbol_title_i.size (); cur_index++)
        {
                cout << the_char;
        }

        cout.setf (ios::left, ios::adjustfield);
        cout << spaces_offset_i;
        for (cur_index = 0; cur_index < code_title_i.size (); cur_index++)
        {
                cout << the_char;
        }

        cout << endl;

} // void BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::print_show_title_S



//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeOneSymbol (
                                        const vector<CODE>&     encoded_msg_i,
                                        unsigned int&           cur_start_position_io,
                                        unsigned int&           cur_symbol_number_io,
                                        vector<CODE>&           cur_symbol_code_o,
                                        SYMBOL&                 cur_symbol_value_o
                                        ) const

{
bool    ret_boolValue = false;
unsigned int cur_index;

const InternalNode<SYMBOL, WEIGHT>*     curPtrInternalNode = &rootNode_;
        ASSERT (!(curPtrInternalNode == NULL));
        ASSERT (!(rootNode_.is_TerminalNode_));
        ASSERT (cur_start_position_io < encoded_msg_i.size ());

CODE            cur_digit;
        //===================
        cur_symbol_code_o = vector<CODE> ();
        for (cur_index = cur_start_position_io;
             cur_index < encoded_msg_i.size ();
             cur_index++
             )
        {
                cur_digit = encoded_msg_i [cur_index];
                if (!((cur_digit >= 0) & (cur_digit < ARY)))
                {
                        FATAL_MSG ("Illegal digit in encoded message"
                                    << endl
                                    << FATAL_SHIFT
                                    << "Digit ["
                                    << cur_index
                                    << "] = "
                                    << encoded_msg_i [cur_index]
                                    << "; Valid range is ["
                                    << 0
                                    << " - "
                                    << (ARY - 1)
                                    << "]"
                                    << endl
                                    << FATAL_SHIFT
                                    << "Note! First digit is 0-th digit"
                                    << endl
                                    << FATAL_SHIFT
                                    << "The encoded message is <"
                                    << gstr_path<ARY> (encoded_msg_i)
                                    << ">"
                                    );
                }
                //======================

                ASSERT (!(curPtrInternalNode->arc_ [cur_digit] == NULL));
                if (curPtrInternalNode->arc_ [cur_digit]->is_TerminalNode_)
                {
                        ret_boolValue = true;
                        break;
                }

                //======================
                ASSERT (!(curPtrInternalNode->arc_ [cur_digit] == NULL));
                curPtrInternalNode = dynamic_cast<InternalNode<SYMBOL, WEIGHT>*> (curPtrInternalNode->arc_ [cur_digit]);
                ASSERT (!(curPtrInternalNode == NULL));
                //======================
        } // for (cur_index =

        //===================
        if (!ret_boolValue)
        {
                cur_index--;
                ERROR_MSG ("Illegal last code in encoded message"
                            << endl
                            << ERROR_SHIFT
                            << "Digits ["
                            << cur_start_position_io
                            << ", "
                            << cur_index
                            << "] = "
                            << gstr_vector (encoded_msg_i, cur_start_position_io, cur_index)
                            << endl
                            << ERROR_SHIFT
                            << "Note! First digit is 0-th digit"
                            << endl
                            << ERROR_SHIFT
                            << "The encoded message is <"
                            << gstr_path<ARY> (encoded_msg_i)
                            << ">"
                            );
                return ret_boolValue;
        }

        //===================
        copy (encoded_msg_i.begin () + cur_start_position_io, encoded_msg_i.begin () + cur_index + 1, back_inserter (cur_symbol_code_o));

        //===================
        ASSERT (mapHuffmanCodes_.count (cur_symbol_code_o));
        cur_symbol_value_o = (*(mapHuffmanCodes_.find (cur_symbol_code_o))).second;
        cur_start_position_io = cur_index + 1;
        cur_symbol_number_io++;

        //===================

        return ret_boolValue;


} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeOneSymbol



//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeOneSymbol (
                                        const vector<CODE>&     encoded_symbol_code_i,
                                        SYMBOL&                 decoded_symbol_value_o
                                        ) const

{
bool    ret_boolValue = false;
        ASSERT (!(encoded_symbol_code_i.empty ()));

const InternalNode<SYMBOL, WEIGHT>*     curPtrInternalNode = &rootNode_;
        ASSERT (!(curPtrInternalNode == NULL));
        ASSERT (!(rootNode_.is_TerminalNode_));

unsigned int    cur_index;
CODE            cur_digit;
        //===================
        for (cur_index = 0; cur_index < (encoded_symbol_code_i.size () - 1); cur_index++)
        {
                cur_digit = encoded_symbol_code_i [cur_index];
                ASSERT (cur_digit >= 0);
                ASSERT (cur_digit < ARY);

                ASSERT (!(curPtrInternalNode->arc_ [cur_digit] == NULL));
                ASSERT (!(curPtrInternalNode->arc_ [cur_digit]->is_TerminalNode_));


                if (curPtrInternalNode->arc_ [cur_digit]->is_TerminalNode_)
                {
                        return ret_boolValue;   // false
                }

                curPtrInternalNode = dynamic_cast<InternalNode<SYMBOL, WEIGHT>*> (curPtrInternalNode->arc_ [cur_digit]);
                ASSERT (!(curPtrInternalNode == NULL));
        } // for (cur_index =

        //================================
        cur_index = encoded_symbol_code_i.size () - 1;
        //===================
        cur_digit = encoded_symbol_code_i [cur_index];
        ASSERT (!(curPtrInternalNode->arc_ [cur_digit] == NULL));
        ASSERT (curPtrInternalNode->arc_ [cur_digit]->is_TerminalNode_);
        if ((!curPtrInternalNode->arc_ [cur_digit]->is_TerminalNode_))
        {
                return ret_boolValue;   // false
        }
        ret_boolValue = true;

        //===================
        ASSERT (mapHuffmanCodes_.count (encoded_symbol_code_i));
        decoded_symbol_value_o = (*(mapHuffmanCodes_.find (encoded_symbol_code_i))).second;
        //===================

        return ret_boolValue;


} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeOneSymbol



//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::testAllCodes (bool show_i) const
{
                //======================
                if (show_i)
                {
                        showAll ("testAllCodes");
                }
                //======================

bool    ret_boolValue = false;
SYMBOL  cur_decoded_symbol_value;
        ASSERT (!(vectorHuffmanCodes_.empty ()));
        for (unsigned int cur_index = 0;
                          cur_index < vectorHuffmanCodes_.size ();
                          cur_index++
                          )
        {
                ret_boolValue = decodeOneSymbol (vectorHuffmanCodes_ [cur_index], cur_decoded_symbol_value);
                if (show_i)
                {
                        cout <<"TESTED : Code <"
                             << gstr_path<ARY> (vectorHuffmanCodes_ [cur_index])
                             << "> == Symbol <"
                             << cur_decoded_symbol_value
                             << ">"
                             << endl;
                }
                ASSERT (ret_boolValue);
        }

        return ret_boolValue;
} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::testAllCodes ()



//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeMsg (
                                        const vector<CODE>&     encoded_msg_i,
                                        vector<SYMBOL>&         decoded_msg_o
                                        ) const

{
bool    ret_boolValue = false;
        if (encoded_msg_i.empty ())
        {
                FATAL_MSG ("Empty message to be decoded");
        }

        //===================
        decoded_msg_o = vector<SYMBOL> ();
        //===================
unsigned int    cur_start_position = 0;
unsigned int    cur_symbol_number = 0;
SYMBOL          cur_symbol_value;
vector<CODE>    cur_symbol_code;
vector<vector<CODE> >   all_symbols_codes;

        while ((ret_boolValue = decodeOneSymbol (
                                        encoded_msg_i,
                                        cur_start_position,
                                        cur_symbol_number,
                                        cur_symbol_code,
                                        cur_symbol_value
                                        )))
        {
                decoded_msg_o.push_back (cur_symbol_value);
                all_symbols_codes.push_back (cur_symbol_code);
                if (!(cur_start_position < encoded_msg_i.size ()))
                {
                        break;
                }
        } // while

        //=================
        if (!ret_boolValue)
        {
                FATAL_MSG ("Cannot decode all message -> "
                                 << gstr_path<ARY> (encoded_msg_i)
                                 << endl
                                 << FATAL_SHIFT
                                 << "Only "
                                 << cur_symbol_number
                                 << " symbols decoded"
                                 << endl
                                 << FATAL_SHIFT
                                 << "Decoded codes -> "
                                 << gstr_vector(all_symbols_codes, string (" "))
                                 << endl
                                 << FATAL_SHIFT
                                 << "Decoded symbols ->  "
                                 << gstr_vector(decoded_msg_o)
                                 );
        }

        //===================
        return ret_boolValue;


} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeMsg


//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::encodeMsg (
                                        const vector<SYMBOL>&   source_msg_i,
                                        vector<CODE>&           encoded_msg_o
                                        ) const

{
bool    ret_boolValue = false;

        ASSERT (!source_msg_i.empty ());
        encoded_msg_o = vector<CODE> ();

vector<CODE>    cur_symbol_code;

        for (unsigned int cur_index = 0;
                          cur_index < source_msg_i.size ();
                          cur_index++
                          )
        {
                if (!(ret_boolValue = encodeOneSymbol (source_msg_i [cur_index], cur_symbol_code)))
                {
                        break;
                }

                copy (cur_symbol_code.begin (), cur_symbol_code.end (), back_inserter (encoded_msg_o));

        }

        // ================
        if (!ret_boolValue)
        {
                FATAL_MSG ("Cannot encode message"
                                 << endl
                                 << FATAL_SHIFT
                                 << gstr_vector (source_msg_i)
                                 );
        }

        return ret_boolValue;


} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::encodeMsg


//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::encodeMsg (
                                        const basic_string<SYMBOL>&     string_source_msg_i,
                                        string&                         string_encoded_msg_o
                                        ) const

{
        //=================================
        if (!(ARY <= 16))
        {
                FATAL_MSG ("Illegal ARY for THIS FUNCTION : Real = "
                            << ARY
                            << "; must be <= 16"
                            );
        }
        ASSERT (ARY <= 16);     // In this function !!!
        //=================================

bool    ret_value = false;


vector <SYMBOL> vector_source_msg (string_source_msg_i.size ());
        for (unsigned int cur_index = 0; cur_index < vector_source_msg.size (); cur_index++)
        {
                vector_source_msg [cur_index] = string_source_msg_i [cur_index];
        }

vector <CODE>   encoded_msg;
        ret_value = encodeMsg (vector_source_msg, encoded_msg);

        //=====================
        string_encoded_msg_o = string ();
        string_encoded_msg_o.resize (encoded_msg.size ());

strstream       tmp_strstream;
        for (unsigned int cur_index = 0; cur_index < string_encoded_msg_o.size (); cur_index++)
        {
                tmp_strstream << encoded_msg [cur_index];
        }
        tmp_strstream << ends;
        string_encoded_msg_o = tmp_strstream.str(); tmp_strstream.rdbuf()->freeze (0);

        //=====================
        return ret_value;
} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::encodeMsg (



//#######################################
template <typename SYMBOL, typename WEIGHT, unsigned int ARY>
bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeMsg (
                                        const string&           string_encoded_msg_i,
                                        basic_string<SYMBOL>&   string_decoded_msg_o
                                        ) const

{
        //=================================
        if (!(ARY <= 16))
        {
                FATAL_MSG ("Illegal ARY for THIS FUNCTION : Real = "
                            << ARY
                            << "; must be <= 16"
                            );
        }
        ASSERT (ARY <= 16);     // In this function !!!
        //=================================

bool    ret_value = false;
vector <CODE>   vector_encoded_msg (string_encoded_msg_i.size ());
unsigned int    eof_int_test;
string          cur_string;
        for (unsigned int cur_index = 0; cur_index < vector_encoded_msg.size (); cur_index++)
        {
                ASSERT (isxdigit (string_encoded_msg_i [cur_index]));

                cur_string = string_encoded_msg_i [cur_index];
                istrstream      int_stream (cur_string.c_str ());

                //int_stream.clear ();
                int_stream >> hex >> vector_encoded_msg [cur_index];
                ASSERT (!(int_stream.eof ()));
                ASSERT (!(int_stream.fail ()));
                ASSERT ((int_stream >> hex >> eof_int_test).eof ());

                int_stream.rdbuf()->freeze (0);
        }

vector <SYMBOL> vector_decoded_msg;
        ret_value = decodeMsg (vector_encoded_msg, vector_decoded_msg);
        //=====================
        string_decoded_msg_o = basic_string<SYMBOL> ();
        string_decoded_msg_o.resize (vector_decoded_msg.size ());
        for (unsigned int cur_index = 0; cur_index < string_decoded_msg_o.size (); cur_index++)
        {
                string_decoded_msg_o [cur_index] = vector_decoded_msg [cur_index];
        }

        //=====================
        return ret_value;
} // bool BasicHuffmanTree<SYMBOL, WEIGHT, ARY>::decodeMsg (





//#######################################################
//##### PART : template class DriedHuffmanTree ##########
//############ Methods ##################################
//#######################################################

//-----------------------
// Constructor-1
template <typename WEIGHT, unsigned int ARY>
DriedHuffmanTree<WEIGHT, ARY>::DriedHuffmanTree (
                        const vector<WEIGHT>& weight_vector_i
                        )
{
        doDriedHuffmanTree (weight_vector_i);
} // DriedHuffmanTree<WEIGHT, ARY>::DriedHuffmanTree ()


//-----------------------
// Constructor-2
template <typename WEIGHT, unsigned int ARY>
DriedHuffmanTree<WEIGHT, ARY>::DriedHuffmanTree (const string& weights_file_name_i)
{
vector<WEIGHT>  weight_vector;

ifstream fin (weights_file_name_i.c_str ());

        if (!fin)
        {
                FATAL_MSG ("Cannot open file <"
                            << weights_file_name_i
                            << "> for reading"
                            << endl
                            << FATAL_SHIFT
                            << "The file must contain weights to be Huffman-coded"
                            );
        }

        copy(istream_iterator<WEIGHT>(fin),
             istream_iterator<WEIGHT>(),
             back_inserter(weight_vector));

        doDriedHuffmanTree (weight_vector);
} // DriedHuffmanTree<WEIGHT, ARY>::DriedHuffmanTree ()


//##########################################################################

//-----------------------
template <typename WEIGHT, unsigned int ARY>
void DriedHuffmanTree<WEIGHT, ARY>::doDriedHuffmanTree (
                        const vector<WEIGHT>& weight_vector_i
                        )
{
vector<Cell<string, WEIGHT> >        data_vector;
        for (unsigned int cur_index = 0;
                          cur_index < weight_vector_i.size ();
                          cur_index++
                          )
        {
                data_vector.push_back (Cell<string, WEIGHT> (
                                        to_str (
                                                cur_index + 1,
                                                get_width (weight_vector_i.size ()),
                                                '0',
                                                "Symbol#"
                                                ),
                                        weight_vector_i [cur_index]
                                        ));
        }


        doBasicHuffmanTree (data_vector);

} // DriedHuffmanTree<WEIGHT, ARY>::DriedHuffmanTree ()


#endif	// huf_methods_H

//#######################################################
//################ END OF FILE ##########################
//#######################################################
------------------- C++ code : END ---------------------- === File #3 of 4 : huf_methods.H ======================== ######################################################### === File #4 of 4 : huf_main.C =========================== ------------------- C++ code : BEGIN --------------------
// ==============================================================
//
//  Copyright (c) 1999-2001 by Alex Vinokur.  This work and all works
//  derived from it may be copied and modified without any
//  restrictions other than that a copy of this copyright notice
//  must be included in any copy of this work or any derived work.
//
// ==============================================================
static char id [] = "@(#)## n-ary Huffman Template Algorithm ## Author : Alex Vinokur ## "__FILE__;

// ##############################################################
// =============================
//  n-ary Huffman Template Algorithm
//  The algorithm (program) contains the following files :
//  - huf_service.H
//  - huf_class.H
//  - huf_methods.H
//  - huf_main.C
// =============================
//
//  FILE : huf_main.C
//
//  AUTHOR : Alex Vinokur
//
//  DESCRIPTION :
//
//         Definition and implementation of the following test classes :
//         ----------------------------------------------
//         - AAA        (non-char) symbol type
//         - BBB        (non-numerical) weight type
//         ----------------------------------------------
//
//         Running the following tests :
//         ----------------------------------------------
//         Test#1.1.  Creating Loaded 5-ary Huffman Tree
//                    from data vector
//                    with char-symbols and int-weights
//
//         Test#1.2.  Encoding and Decoding vector-message
//                    using 5-ary Huffman Tree
//
//         Test#1.3.  Encoding and Decoding string-message
//                    using 5-ary Huffman Tree
//
//         Test#2.    Creating Loaded 24-ary Huffman Tree
//                    from data vector
//                    with char-symbols and int-weights
//
//         Test#3.1.  Creating Loaded Binary Huffman Tree
//                    from data vector
//                    with char-symbols and int-weights
//
//         Test#3.2.  Encoding and Decoding vector-message
//                    using Binary Huffman Tree
//
//         Test#3.3.  Encoding and Decoding string-message
//                    using Binary Huffman Tree
//
//         Test#4.    Creating Dried (Unload) Binary Huffman Tree
//                    from data vector
//                    with int-weights
//                    Note. This vector contains Fibonacci sequence.
//
//         Test#5.    Creating Dried (Unload) Binary Huffman Tree
//                    from data file
//                    with int-weights
//
//         Test#6.    Creating Loaded Binary Huffman Tree
//                    from data file
//                    with char-symbols and int-weights
//
//         Test#7.    Creating Loaded Binary Huffman Tree
//                    from data vector
//                    with string-symbols and float-weights
//
//         Test#8.    Creating Loaded Binary Huffman Tree
//                    from data vector
//                    with AAA-symbols and BBB-weights
//         ----------------------------------------------
//
//  DATE           VERSION
//  ----           -------
//  Aug-26-1999    NHTA 1.0
//  Jul-05-2001    NHTA 1.1
//  Sep-11-2001    NHTA 1.2
//
// ##############################################################


//=======================
#include "huf_methods.H"
//=======================



//###################################################
//############## "Symbols" Test Class ###############
//###################################################
class AAA
{
friend bool operator< (const AAA& inst1_i, const AAA& inst2_i);
friend ostream& operator<< (ostream& o, const AAA& instance_i);
        private :
                static unsigned int     counter_s;
                unsigned int            counter_;
        public :
                AAA () {counter_ = ++counter_s;}
                ~AAA () {}
};

//=========================
ostream& operator<< (ostream& o, const AAA& instance_i)
{
        return o << "AAA_" << instance_i.counter_;
}
//----------------------
bool operator< (const AAA& inst1_i, const AAA& inst2_i)
{
        return (inst1_i.counter_ < inst2_i.counter_);
}




//###################################################
//############## "Weight" Test Class ################
//###################################################
class BBB
{
friend ostream& operator<< (ostream& o, const BBB& instance_i);
friend bool operator< (const BBB& inst1_i, const BBB& inst2_i);
friend bool operator== (const BBB& inst1_i, const BBB& inst2_i);
friend BBB operator* (const BBB& inst1_i, unsigned int int_value_i);
friend BBB operator/ (const BBB& inst1_i, unsigned int int_value_i);
        private :
                int                     value_;
                static unsigned int     counter_s;
                unsigned int            counter_;

        public :
                BBB () {counter_ = ++counter_s; value_ = rand ();}
                ~BBB () {}

                BBB& operator+= (const BBB& inst_i)
                {
                        value_ += inst_i.value_;
                        return (*this);
                }

};

//=========================
ostream& operator<< (ostream& o, const BBB& instance_i)
{
        return o << "BBB_" << instance_i.counter_;
        //#########################################
        // Note! This operator shows bogus weight.
        // Real value (instance_i.value_) hidden.
        //#########################################
}
//----------------------
bool operator< (const BBB& inst1_i, const BBB& inst2_i)
{
        return (inst1_i.value_ < inst2_i.value_);
}
//----------------------
bool operator== (const BBB& inst1_i, const BBB& inst2_i)
{
        return (inst1_i.value_ == inst2_i.value_);
}
//----------------------
BBB operator* (const BBB& inst1_i, unsigned int int_value_i)
{
BBB bbb;
        bbb.value_ = bbb.value_*int_value_i;
        return bbb;
}
//----------------------
BBB operator/ (const BBB& inst1_i, unsigned int int_value_i)
{
BBB bbb;
        bbb.value_ = bbb.value_/int_value_i;
        return bbb;
}



//#####################################################
//=========================
unsigned int    AAA::counter_s (0);
unsigned int    BBB::counter_s (0);
//=========================


//#####################################################
//############# main ##################################
//#####################################################
//==============================
int main (int argc, char **argv)
{

        //===========================================
vector<Cell<char, int> >        data_vector_01;
        for (unsigned char cur_char = 0x20; cur_char < 0x7d; cur_char++)
        {
                data_vector_01.push_back (Cell<char, int> (cur_char, ((cur_char%19 + 3)) * 7));
        }


LoadedHuffmanTree<char, int, 5>         tree_01 (data_vector_01);
        tree_01.showAll ("Test#1.1 : Creating Loaded 5-ary Huffman Tree from <char, int>-data vector");

LoadedHuffmanTree<char, int, 24>        tree_02 (data_vector_01);
        tree_02.showAll ("Test#2 : Creating Loaded 24-ary Huffman Tree from <char, int>-data vector");

LoadedHuffmanTree<char, int>            tree_03 (data_vector_01);
        tree_03.showAll ("Test#3.1 : Creating Loaded Binary Huffman Tree from <char, int>-data vector");

        //=======================================================
vector<char>    vector_source_msg;
vector<CODE>    vector_encoded_msg;
vector<char>    vector_decoded_msg;

string          string_source_msg;
string          string_encoded_msg;
string          string_decoded_msg;


        //============ vector msg ===============================
        cout << endl << "\tTest#1.2 : Encoding and Decoding vector-message using 5-ary Huffman Tree" << endl;

        fill_vector (vector_source_msg, string ("Hi, people! This is vector message from 5-ary Huffman Tree"));

        cout << "Source Message  : " << gstr_vector (vector_source_msg) << endl;

        if (tree_01.encodeMsg (vector_source_msg, vector_encoded_msg))
        {
                cout << "Encoded Message : " << gstr_vector (vector_encoded_msg) << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << gstr_vector (vector_source_msg) << ">" << endl;
        }
        if (tree_01.decodeMsg (vector_encoded_msg, vector_decoded_msg))
        {
                cout << "Decoded Message : " << gstr_vector (vector_decoded_msg) << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << gstr_vector (vector_encoded_msg) << ">" << endl;
        }



        //============ string msg ===============================
        cout << endl << "\tTest#1.3 : Encoding and Decoding string-message using 5-ary Huffman Tree" << endl;

        string_source_msg = "Hi, people! This is string message from 5-ary Huffman Tree";

        cout << "Source Message  : " << string_source_msg << endl;

        if (tree_01.encodeMsg (string_source_msg, string_encoded_msg))
        {
                cout << "Encoded Message : " << string_encoded_msg << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << string_source_msg << ">" << endl;
        }

        if (tree_01.decodeMsg (string_encoded_msg, string_decoded_msg))
        {
                cout << "Decoded Message : " << string_decoded_msg << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << string_encoded_msg << ">" << endl;
        }


        //======================================================
        //============ vector msg ===============================
        cout << endl << "\tTest#3.2 : Encoding and Decoding vector-message using Binary Huffman Tree" << endl;

        fill_vector (vector_source_msg, string ("Hi, people! This is vector message from Binary Huffman Tree"));

        cout << "Source Message  : " << gstr_vector (vector_source_msg) << endl;

        if (tree_03.encodeMsg (vector_source_msg, vector_encoded_msg))
        {
                cout << "Encoded Message : " << gstr_vector (vector_encoded_msg) << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << gstr_vector (vector_source_msg) << ">" << endl;
        }
        if (tree_03.decodeMsg (vector_encoded_msg, vector_decoded_msg))
        {
                cout << "Decoded Message : " << gstr_vector (vector_decoded_msg) << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << gstr_vector (vector_encoded_msg) << ">" << endl;
        }



        //============ string msg ===============================
        cout << endl << "\tTest#3.3 : Encoding and Decoding string-message using Binary Huffman Tree" << endl;

        string_source_msg = "Hi, people! This is string message from Binary Huffman Tree";

        cout << "Source Message  : " << string_source_msg << endl;

        if (tree_03.encodeMsg (string_source_msg, string_encoded_msg))
        {
                cout << "Encoded Message : " << string_encoded_msg << endl;
        }
        else
        {
                cout << "Cannot encode Message <" << string_source_msg << ">" << endl;
        }

        if (tree_03.decodeMsg (string_encoded_msg, string_decoded_msg))
        {
                cout << "Decoded Message : " << string_decoded_msg << endl;
        }
        else
        {
                cout << "Cannot decode encoded Message <" << string_encoded_msg << ">" << endl;
        }




        //==============================================
        //==============================================
        //==============================================
vector<int>     weights_vector_01;
        weights_vector_01.push_back (1);
        weights_vector_01.push_back (1);
const unsigned int      this_start_index = weights_vector_01.size ();
        for (unsigned int the_index = this_start_index;
                          the_index < (this_start_index + 21);
                          the_index++)
        {
                weights_vector_01.push_back (weights_vector_01 [the_index - 2] + weights_vector_01 [the_index - 1]);
        }

DriedHuffmanTree<int>   tree_04 (weights_vector_01);
        tree_04.showAll ("Test#4 : Creating Dried Binary Huffman Tree from <int>-weights vector (Fibonacci sequence)");

DriedHuffmanTree<int>   tree_05 ("weights_file_01");
        tree_05.showAll ("Test#5 : Creating Dried Binary Huffman Tree from <int>-weights file");

LoadedHuffmanTree<char, int>    tree_06 ("data_file_01");
        tree_06.showAll ("Test#6 : Creating Loaded Binary Huffman Tree from <char, int>-data file");


        //===========================================
vector<Cell<string, float> >    data_vector_02;
        data_vector_02.push_back (Cell<string, float> ("a1", 0.0022));
        data_vector_02.push_back (Cell<string, float> ("aa22", 0.002));
        data_vector_02.push_back (Cell<string, float> ("aaa333", 0.02));
        data_vector_02.push_back (Cell<string, float> ("bx1", 0.0001));
        data_vector_02.push_back (Cell<string, float> ("bbyy22", 0.007));
        data_vector_02.push_back (Cell<string, float> ("czzz1", 0.0013));
        data_vector_02.push_back (Cell<string, float> ("cczzzzz22", 0.003));
        data_vector_02.push_back (Cell<string, float> ("ccczzzzzzzz333", 0.023));
LoadedHuffmanTree<string, float>                tree_07 (data_vector_02);
        tree_07.showAll ("Test#7 : Creating Loaded Binary Huffman Tree from <string, float>-data vector");


        //===========================================
vector<Cell<AAA, BBB> > data_vector_03;
        for (unsigned int the_index = 0;
                          the_index < 5;
                          the_index++)
        {
                data_vector_03.push_back (Cell<AAA, BBB> ());
        }
LoadedHuffmanTree<AAA, BBB>             tree_08 (data_vector_03);
        tree_08.showAll ("Test#8 : Creating Loaded Binary Huffman Tree from <AAA, BBB>-data vector");

        return 0;

} // main


//#######################################################
//################ END OF FILE ##########################
//#######################################################
------------------- C++ code : END ---------------------- === File #4 of 4 : huf_main.C ===========================
====================================================
==================== 6. Compiling ==================

//#########################################################
//------------------- System & Compiler  ------------------

Windows98

gpp :  GNU C++ version 2.95.3 20010315/djgpp (release) (djgpp) 
       compiled by GNU C version 2.95.3 20010315/djgpp (release).

//-------------------- Compiling : BEGIN ------------------

%gpp huf_main.C

//-------------------- Compiling : END --------------------
====================================================
===================== 7. Running ===================

//#########################################################
//------------------- Running Results : BEGIN -------------

%a.exe


########### showAll (BEGIN) ###########
        ===== Test#1.1 : Creating Loaded 5-ary Huffman Tree from <char, int>-data vector =====


        -> This is 5-ary Huffman Coding <-
        Alphabet size           = 93
        Shortest code size      = 2
        Longest code size       = 4

        Weights sum             = 7777
        Average weight          = 83

        Code-sizes sum          = 279
        Average code-size       = 3

        Weighted code-sizes sum = 22141
        Ave. weighted code-size = 238




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol   Code
      ------   ------   ----
         112            404
         119   !        414
         126   "        424
         133   #        434
         140   $        00
         147   %        10
          21   &        3400
          28   '        4400
          35   (        200
          42   )        210
          49   *        220
          56   +        230
          63   ,        240
          70   -        300
          77   .        310
          84   /        320
          91   0        330
          98   1        341
         105   2        400
         112   3        410
         119   4        420
         126   5        430
         133   6        441
         140   7        01
         147   8        11
          21   9        3401
          28   :        4401
          35   ;        201
          42   <        211
          49   =        221
          56   >        231
          63   ?        241
          70   @        301
          77   A        311
          84   B        321
          91   C        331
          98   D        342
         105   E        401
         112   F        411
         119   G        421
         126   H        431
         133   I        442
         140   J        02
         147   K        12
          21   L        3402
          28   M        4402
          35   N        202
          42   O        212
          49   P        222
          56   Q        232
          63   R        242
          70   S        302
          77   T        312
          84   U        322
          91   V        332
          98   W        343
         105   X        402
         112   Y        412
         119   Z        422
         126   [        432
         133   \        443
         140   ]        03
         147   ^        13
          21   _        3403
          28   `        4403
          35   a        203
          42   b        213
          49   c        223
          56   d        233
          63   e        243
          70   f        303
          77   g        313
          84   h        323
          91   i        333
          98   j        344
         105   k        403
         112   l        413
         119   m        423
         126   n        433
         133   o        444
         140   p        04
         147   q        14
          21   r        3404
          28   s        4404
          35   t        204
          42   u        214
          49   v        224
          56   w        234
          63   x        244
          70   y        304
          77   z        314
          84   {        324
          91   |        334


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol   Code
      ------   ------   ----
         140   $        00
         140   7        01
         140   J        02
         140   ]        03
         140   p        04
         147   %        10
         147   8        11
         147   K        12
         147   ^        13
         147   q        14
          35   (        200
          35   ;        201
          35   N        202
          35   a        203
          35   t        204
          42   )        210
          42   <        211
          42   O        212
          42   b        213
          42   u        214
          49   *        220
          49   =        221
          49   P        222
          49   c        223
          49   v        224
          56   +        230
          56   >        231
          56   Q        232
          56   d        233
          56   w        234
          63   ,        240
          63   ?        241
          63   R        242
          63   e        243
          63   x        244
          70   -        300
          70   @        301
          70   S        302
          70   f        303
          70   y        304
          77   .        310
          77   A        311
          77   T        312
          77   g        313
          77   z        314
          84   /        320
          84   B        321
          84   U        322
          84   h        323
          84   {        324
          91   0        330
          91   C        331
          91   V        332
          91   i        333
          91   |        334
          21   &        3400
          21   9        3401
          21   L        3402
          21   _        3403
          21   r        3404
          98   1        341
          98   D        342
          98   W        343
          98   j        344
         105   2        400
         105   E        401
         105   X        402
         105   k        403
         112            404
         112   3        410
         112   F        411
         112   Y        412
         112   l        413
         119   !        414
         119   4        420
         119   G        421
         119   Z        422
         119   m        423
         126   "        424
         126   5        430
         126   H        431
         126   [        432
         126   n        433
         133   #        434
          28   '        4400
          28   :        4401
          28   M        4402
          28   `        4403
          28   s        4404
         133   6        441
         133   I        442
         133   \        443
         133   o        444


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol   Code
      ------   ------   ----
         140   $        00
         140   7        01
         140   J        02
         140   ]        03
         140   p        04
         147   %        10
         147   8        11
         147   K        12
         147   ^        13         147   q        14
          35   (        200
          35   ;        201
          35   N        202
          35   a        203
          35   t        204
          42   )        210
          42   <        211
          42   O        212
          42   b        213
          42   u        214
          49   *        220
          49   =        221
          49   P        222
          49   c        223
          49   v        224
          56   +        230
          56   >        231
          56   Q        232
          56   d        233
          56   w        234
          63   ,        240
          63   ?        241
          63   R        242
          63   e        243
          63   x        244
          70   -        300
          70   @        301
          70   S        302
          70   f        303
          70   y        304
          77   .        310
          77   A        311
          77   T        312
          77   g        313
          77   z        314
          84   /        320
          84   B        321
          84   U        322
          84   h        323
          84   {        324
          91   0        330
          91   C        331
          91   V        332
          91   i        333
          91   |        334
          98   1        341
          98   D        342
          98   W        343
          98   j        344
         105   2        400
         105   E        401
         105   X        402
         105   k        403
         112            404
         112   3        410
         112   F        411
         112   Y        412
         112   l        413
         119   !        414
         119   4        420
         119   G        421
         119   Z        422
         119   m        423
         126   "        424
         126   5        430
         126   H        431
         126   [        432
         126   n        433
         133   #        434
         133   6        441
         133   I        442
         133   \        443
         133   o        444
          21   &        3400
          21   9        3401
          21   L        3402
          21   _        3403
          21   r        3404
          28   '        4400
          28   :        4401
          28   M        4402
          28   `        4403
          28   s        4404


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol   Code
      ------   ------   ----
          21   &        3400
          21   9        3401
          21   L        3402
          21   _        3403
          21   r        3404
          28   '        4400
          28   :        4401
          28   M        4402
          28   `        4403
          28   s        4404
          35   (        200
          35   ;        201
          35   N        202
          35   a        203
          35   t        204
          42   )        210
          42   <        211
          42   O        212
          42   b        213
          42   u        214
          49   *        220
          49   =        221
          49   P        222
          49   c        223
          49   v        224
          56   +        230
          56   >        231
          56   Q        232
          56   d        233
          56   w        234
          63   ,        240
          63   ?        241
          63   R        242
          63   e        243
          63   x        244
          70   -        300
          70   @        301
          70   S        302
          70   f        303
          70   y        304
          77   .        310
          77   A        311
          77   T        312
          77   g        313
          77   z        314
          84   /        320
          84   B        321
          84   U        322
          84   h        323
          84   {        324
          91   0        330
          91   C        331
          91   V        332
          91   i        333
          91   |        334
          98   1        341
          98   D        342
          98   W        343
          98   j        344
         105   2        400
         105   E        401
         105   X        402
         105   k        403         112            404
         112   3        410
         112   F        411
         112   Y        412
         112   l        413
         119   !        414
         119   4        420
         119   G        421
         119   Z        422
         119   m        423
         126   "        424
         126   5        430
         126   H        431
         126   [        432
         126   n        433
         133   #        434
         133   6        441
         133   I        442
         133   \        443
         133   o        444
         140   $        00
         140   7        01
         140   J        02
         140   ]        03
         140   p        04
         147   %        10
         147   8        11
         147   K        12
         147   ^        13
         147   q        14

########### showAll (END) #############
########### showAll (BEGIN) ###########
        ===== Test#2 : Creating Loaded 24-ary Huffman Tree from <char, int>-data vector =====


        -> This is 24-ary Huffman Coding <-
        Alphabet size           = 93
        Shortest code size      = 1
        Longest code size       = 2

        Weights sum             = 7777
        Average weight          = 83

        Code-sizes sum          = 165
        Average code-size       = 1.77419

        Weighted code-sizes sum = 12705
        Ave. weighted code-size = 136




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol   Code
      ------   ------   ----
         112            2.15
         119   !        2.20
         126   "        4
         133   #        9
         140   $        14
         147   %        19
          21   &        0.0
          28   '        0.5
          35   (        0.10
          42   )        0.15
          49   *        0.20
          56   +        1.1
          63   ,        1.6
          70   -        1.11
          77   .        1.16
          84   /        1.21
          91   0        2.2
          98   1        2.7
         105   2        2.11
         112   3        2.16
         119   4        2.21
         126   5        5
         133   6        10
         140   7        15
         147   8        20
          21   9        0.1
          28   :        0.6
          35   ;        0.11
          42   <        0.16
          49   =        0.21
          56   >        1.2
          63   ?        1.7
          70   @        1.12
          77   A        1.17
          84   B        1.22
          91   C        2.3
          98   D        2.8
         105   E        2.12
         112   F        2.17
         119   G        2.22
         126   H        6
         133   I        11
         140   J        16
         147   K        21
          21   L        0.2
          28   M        0.7
          35   N        0.12
          42   O        0.17
          49   P        0.22
          56   Q        1.3
          63   R        1.8
          70   S        1.13
          77   T        1.18
          84   U        1.23
          91   V        2.4
          98   W        2.9
         105   X        2.13
         112   Y        2.18
         119   Z        2.23
         126   [        7
         133   \        12
         140   ]        17
         147   ^        22
          21   _        0.3
          28   `        0.8
          35   a        0.13
          42   b        0.18
          49   c        0.23
          56   d        1.4
          63   e        1.9
          70   f        1.14
          77   g        1.19
          84   h        2.0
          91   i        2.5
          98   j        2.10
         105   k        2.14
         112   l        2.19
         119   m        3
         126   n        8
         133   o        13
         140   p        18
         147   q        23
          21   r        0.4
          28   s        0.9
          35   t        0.14
          42   u        0.19
          49   v        1.0
          56   w        1.5
          63   x        1.10
          70   y        1.15
          77   z        1.20
          84   {        2.1
          91   |        2.6


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol   Code
      ------   ------   ----
          21   &        0.0
          21   9        0.1
          21   L        0.2
          21   _        0.3
          21   r        0.4
          28   '        0.5
          28   :        0.6
          28   M        0.7
          28   `        0.8
          28   s        0.9
          35   (        0.10
          35   ;        0.11
          35   N        0.12
          35   a        0.13
          35   t        0.14
          42   )        0.15
          42   <        0.16
          42   O        0.17
          42   b        0.18
          42   u        0.19
          49   *        0.20
          49   =        0.21
          49   P        0.22
          49   c        0.23
          49   v        1.0
          56   +        1.1
          56   >        1.2
          56   Q        1.3
          56   d        1.4
          56   w        1.5
          63   ,        1.6
          63   ?        1.7
          63   R        1.8
          63   e        1.9
          63   x        1.10
          70   -        1.11
          70   @        1.12
          70   S        1.13
          70   f        1.14
          70   y        1.15
          77   .        1.16
          77   A        1.17
          77   T        1.18
          77   g        1.19
          77   z        1.20
          84   /        1.21
          84   B        1.22
          84   U        1.23
          84   h        2.0
          84   {        2.1
          91   0        2.2
          91   C        2.3
          91   V        2.4
          91   i        2.5
          91   |        2.6
          98   1        2.7
          98   D        2.8
          98   W        2.9
          98   j        2.10
         105   2        2.11
         105   E        2.12
         105   X        2.13
         105   k        2.14
         112            2.15
         112   3        2.16
         112   F        2.17
         112   Y        2.18
         112   l        2.19
         119   !        2.20
         119   4        2.21
         119   G        2.22
         119   Z        2.23
         119   m        3
         126   "        4
         126   5        5
         126   H        6
         126   [        7
         126   n        8
         133   #        9
         133   6        10
         133   I        11
         133   \        12
         133   o        13
         140   $        14
         140   7        15
         140   J        16
         140   ]        17
         140   p        18
         147   %        19
         147   8        20
         147   K        21
         147   ^        22
         147   q        23


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol   Code
      ------   ------   ----
         119   m        3
         126   "        4
         126   5        5
         126   H        6
         126   [        7
         126   n        8
         133   #        9
         133   6        10
         133   I        11
         133   \        12
         133   o        13
         140   $        14
         140   7        15
         140   J        16
         140   ]        17
         140   p        18
         147   %        19
         147   8        20
         147   K        21
         147   ^        22
         147   q        23
          21   &        0.0
          21   9        0.1
          21   L        0.2
          21   _        0.3
          21   r        0.4
          28   '        0.5
          28   :        0.6
          28   M        0.7
          28   `        0.8
          28   s        0.9
          35   (        0.10
          35   ;        0.11
          35   N        0.12
          35   a        0.13
          35   t        0.14
          42   )        0.15
          42   <        0.16
          42   O        0.17
          42   b        0.18
          42   u        0.19
          49   *        0.20
          49   =        0.21
          49   P        0.22
          49   c        0.23
          49   v        1.0
          56   +        1.1
          56   >        1.2
          56   Q        1.3
          56   d        1.4
          56   w        1.5
          63   ,        1.6
          63   ?        1.7
          63   R        1.8
          63   e        1.9
          63   x        1.10
          70   -        1.11
          70   @        1.12
          70   S        1.13
          70   f        1.14
          70   y        1.15
          77   .        1.16
          77   A        1.17
          77   T        1.18
          77   g        1.19
          77   z        1.20
          84   /        1.21
          84   B        1.22
          84   U        1.23
          84   h        2.0
          84   {        2.1
          91   0        2.2
          91   C        2.3
          91   V        2.4
          91   i        2.5
          91   |        2.6
          98   1        2.7
          98   D        2.8
          98   W        2.9
          98   j        2.10
         105   2        2.11
         105   E        2.12
         105   X        2.13
         105   k        2.14
         112            2.15
         112   3        2.16
         112   F        2.17
         112   Y        2.18
         112   l        2.19
         119   !        2.20
         119   4        2.21
         119   G        2.22
         119   Z        2.23


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol   Code
      ------   ------   ----
          21   &        0.0
          21   9        0.1
          21   L        0.2
          21   _        0.3
          21   r        0.4
          28   '        0.5
          28   :        0.6
          28   M        0.7
          28   `        0.8
          28   s        0.9
          35   (        0.10
          35   ;        0.11
          35   N        0.12
          35   a        0.13
          35   t        0.14
          42   )        0.15
          42   <        0.16
          42   O        0.17
          42   b        0.18
          42   u        0.19
          49   *        0.20
          49   =        0.21
          49   P        0.22
          49   c        0.23
          49   v        1.0
          56   +        1.1
          56   >        1.2
          56   Q        1.3
          56   d        1.4
          56   w        1.5
          63   ,        1.6
          63   ?        1.7
          63   R        1.8
          63   e        1.9
          63   x        1.10
          70   -        1.11
          70   @        1.12
          70   S        1.13
          70   f        1.14
          70   y        1.15
          77   .        1.16
          77   A        1.17
          77   T        1.18
          77   g        1.19
          77   z        1.20
          84   /        1.21
          84   B        1.22
          84   U        1.23
          84   h        2.0
          84   {        2.1
          91   0        2.2
          91   C        2.3
          91   V        2.4
          91   i        2.5
          91   |        2.6
          98   1        2.7
          98   D        2.8
          98   W        2.9
          98   j        2.10
         105   2        2.11
         105   E        2.12
         105   X        2.13
         105   k        2.14
         112            2.15
         112   3        2.16
         112   F        2.17
         112   Y        2.18
         112   l        2.19
         119   !        2.20
         119   4        2.21
         119   G        2.22
         119   Z        2.23
         119   m        3
         126   "        4
         126   5        5
         126   H        6
         126   [        7
         126   n        8
         133   #        9
         133   6        10
         133   I        11
         133   \        12
         133   o        13
         140   $        14
         140   7        15
         140   J        16
         140   ]        17
         140   p        18
         147   %        19
         147   8        20
         147   K        21
         147   ^        22
         147   q        23

########### showAll (END) #############
########### showAll (BEGIN) ###########
        ===== Test#3.1 : Creating Loaded Binary Huffman Tree from <char, int>-data vector =====


        -> This is Binary Huffman Coding <-
        Alphabet size           = 93
        Shortest code size      = 6
        Longest code size       = 9

        Weights sum             = 7777
        Average weight          = 83

        Code-sizes sum          = 629
        Average code-size       = 6.76344

        Weighted code-sizes sum = 49749
        Ave. weighted code-size = 534




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol   Code
      ------   ------   ----
         112            011000
         119   !        011100
         126   "        100111
         133   #        101010
         140   $        101110
         147   %        111000
          21   &        110100000
          28   '        00101101
          35   (        11001100
          42   )        11111111
          49   *        0010111
          56   +        0100100
          63   ,        0110101
          70   -        1100100
          77   .        1111000
          84   /        000000
          91   0        000011
          98   1        001001
         105   2        001111
         112   3        011001
         119   4        011101
         126   5        100100
         133   6        101011
         140   7        101111
         147   8        111001
          21   9        110100001
          28   :        01011100
          35   ;        11001101
          42   <        11110100
          49   =        0010100
          56   >        0100101
          63   ?        1000000
          70   @        1100101
          77   A        1111001
          84   B        000001
          91   C        000100
          98   D        001100
         105   E        010000
         112   F        010100
         119   G        011110
         126   H        100101
         133   I        101000
         140   J        110000
         147   K        110110
          21   L        111111100
          28   M        01011101
          35   N        11001110
          42   O        11110101
          49   P        0010101
          56   Q        0101100
          63   R        1000001
          70   S        1011000
          77   T        1110100
          84   U        1111100
          91   V        000101
          98   W        001101
         105   X        010001
         112   Y        010101
         119   Z        011111
         126   [        100010
         133   \        101001
         140   ]        110001
         147   ^        110111
          21   _        111111101
          28   `        01011110
          35   a        11001111
          42   b        11111100
          49   c        0010000
          56   d        0101101
          63   e        1001100
          70   f        1011001
          77   g        1110101
          84   h        1111101
          91   i        000110
          98   j        001110
         105   k        010011
         112   l        011011
         119   m        100001
         126   n        100011
         133   o        101101
         140   p        110101
         147   q        111011
          21   r        00101100
          28   s        01011111          35   t        11010001
          42   u        11111101
          49   v        0010001
          56   w        0110100
          63   x        1001101
          70   y        1101001
          77   z        1111011
          84   {        000010
          91   |        000111


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol   Code
      ------   ------   ----
          84   /        000000
          84   B        000001
          84   {        000010
          91   0        000011
          91   C        000100
          91   V        000101
          91   i        000110
          91   |        000111
          49   c        0010000
          49   v        0010001
          98   1        001001
          49   =        0010100
          49   P        0010101
          21   r        00101100
          28   '        00101101
          49   *        0010111
          98   D        001100
          98   W        001101
          98   j        001110
         105   2        001111
         105   E        010000
         105   X        010001
          56   +        0100100
          56   >        0100101
         105   k        010011
         112   F        010100
         112   Y        010101
          56   Q        0101100
          56   d        0101101
          28   :        01011100
          28   M        01011101
          28   `        01011110
          28   s        01011111
         112            011000
         112   3        011001
          56   w        0110100
          63   ,        0110101
         112   l        011011
         119   !        011100
         119   4        011101
         119   G        011110
         119   Z        011111
          63   ?        1000000
          63   R        1000001
         119   m        100001
         126   [        100010
         126   n        100011
         126   5        100100
         126   H        100101
          63   e        1001100
          63   x        1001101
         126   "        100111
         133   I        101000
         133   \        101001
         133   #        101010
         133   6        101011
          70   S        1011000
          70   f        1011001
         133   o        101101
         140   $        101110
         140   7        101111
         140   J        110000
         140   ]        110001
          70   -        1100100
          70   @        1100101
          35   (        11001100
          35   ;        11001101
          35   N        11001110
          35   a        11001111
          21   &        110100000
          21   9        110100001
          35   t        11010001
          70   y        1101001
         140   p        110101
         147   K        110110
         147   ^        110111
         147   %        111000
         147   8        111001
          77   T        1110100
          77   g        1110101
         147   q        111011
          77   .        1111000
          77   A        1111001
          42   <        11110100
          42   O        11110101
          77   z        1111011
          84   U        1111100
          84   h        1111101
          42   b        11111100
          42   u        11111101
          21   L        111111100
          21   _        111111101
          42   )        11111111


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol   Code
      ------   ------   ----
          84   /        000000
          84   B        000001
          84   {        000010
          91   0        000011
          91   C        000100
          91   V        000101
          91   i        000110
          91   |        000111
          98   1        001001
          98   D        001100
          98   W        001101
          98   j        001110
         105   2        001111
         105   E        010000
         105   X        010001
         105   k        010011
         112   F        010100
         112   Y        010101
         112            011000
         112   3        011001
         112   l        011011
         119   !        011100
         119   4        011101
         119   G        011110
         119   Z        011111
         119   m        100001
         126   [        100010
         126   n        100011
         126   5        100100
         126   H        100101
         126   "        100111
         133   I        101000
         133   \        101001
         133   #        101010
         133   6        101011
         133   o        101101
         140   $        101110
         140   7        101111
         140   J        110000
         140   ]        110001
         140   p        110101
         147   K        110110
         147   ^        110111
         147   %        111000
         147   8        111001
         147   q        111011
          49   c        0010000
          49   v        0010001
          49   =        0010100
          49   P        0010101
          49   *        0010111
          56   +        0100100
          56   >        0100101
          56   Q        0101100
          56   d        0101101
          56   w        0110100
          63   ,        0110101
          63   ?        1000000
          63   R        1000001
          63   e        1001100
          63   x        1001101
          70   S        1011000
          70   f        1011001
          70   -        1100100
          70   @        1100101
          70   y        1101001
          77   T        1110100
          77   g        1110101
          77   .        1111000
          77   A        1111001
          77   z        1111011
          84   U        1111100
          84   h        1111101
          21   r        00101100
          28   '        00101101
          28   :        01011100
          28   M        01011101
          28   `        01011110
          28   s        01011111
          35   (        11001100
          35   ;        11001101
          35   N        11001110
          35   a        11001111
          35   t        11010001
          42   <        11110100
          42   O        11110101
          42   b        11111100
          42   u        11111101
          42   )        11111111
          21   &        110100000
          21   9        110100001
          21   L        111111100
          21   _        111111101


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol   Code
      ------   ------   ----
          21   &        110100000
          21   9        110100001
          21   L        111111100
          21   _        111111101
          21   r        00101100
          28   '        00101101
          28   :        01011100
          28   M        01011101
          28   `        01011110
          28   s        01011111
          35   (        11001100
          35   ;        11001101
          35   N        11001110
          35   a        11001111
          35   t        11010001
          42   )        11111111
          42   <        11110100
          42   O        11110101
          42   b        11111100
          42   u        11111101
          49   *        0010111
          49   =        0010100
          49   P        0010101
          49   c        0010000
          49   v        0010001
          56   +        0100100
          56   >        0100101
          56   Q        0101100
          56   d        0101101
          56   w        0110100
          63   ,        0110101
          63   ?        1000000
          63   R        1000001
          63   e        1001100
          63   x        1001101
          70   -        1100100
          70   @        1100101
          70   S        1011000
          70   f        1011001
          70   y        1101001
          77   .        1111000
          77   A        1111001
          77   T        1110100
          77   g        1110101
          77   z        1111011
          84   /        000000
          84   B        000001
          84   U        1111100
          84   h        1111101
          84   {        000010
          91   0        000011
          91   C        000100
          91   V        000101
          91   i        000110
          91   |        000111
          98   1        001001
          98   D        001100
          98   W        001101
          98   j        001110
         105   2        001111
         105   E        010000
         105   X        010001
         105   k        010011
         112            011000
         112   3        011001
         112   F        010100
         112   Y        010101
         112   l        011011
         119   !        011100
         119   4        011101
         119   G        011110
         119   Z        011111
         119   m        100001
         126   "        100111
         126   5        100100
         126   H        100101
         126   [        100010
         126   n        100011
         133   #        101010
         133   6        101011
         133   I        101000
         133   \        101001
         133   o        101101
         140   $        101110
         140   7        101111
         140   J        110000
         140   ]        110001
         140   p        110101
         147   %        111000
         147   8        111001
         147   K        110110
         147   ^        110111
         147   q        111011

########### showAll (END) #############

        Test#1.2 : Encoding and Decoding vector-message using 5-ary Huffman Tree
Source Message  : Hi, people! This is vector message from 5-ary Huffman Tree
Encoded Message : 431333240404042434440441324341440431232333344044043334404404224243223204444340440442324344044404203313243404303340444442340443030020334043044044312143033034232034334043123404243243
Decoded Message : Hi, people! This is vector message from 5-ary Huffman Tree

        Test#1.3 : Encoding and Decoding string-message using 5-ary Huffman Tree
Source Message  : Hi, people! This is string message from 5-ary Huffman Tree
Encoded Message : 4313332404040424344404413243414404312323333440440433344044044404204340433343331340442324344044404203313243404303340444442340443030020334043044044312143033034232034334043123404243243
Decoded Message : Hi, people! This is string message from 5-ary Huffman Tree

        Test#3.2 : Encoding and Decoding vector-message using Binary Huffman Tree
Source Message  : Hi, people! This is vector message from Binary Huffman Tree
Encoded Message : 10010100011001101010110001101011001100101101110101011011100110001110001100011101001111101000110010111110110000001100101111101100000100011001100001000011010001101101001011000110001000011001100010111110101111111001111111010110011000110001011001001011001011011000010110000000010001101000111100111100101100110100101100010010111111101101100110110011000011100111110001101100011101000010110010011001001100
Decoded Message : Hi, people! This is vector message from Binary Huffman Tree

        Test#3.3 : Encoding and Decoding string-message using Binary Huffman Tree
Source Message  : Hi, people! This is string message from Binary Huffman Tree
Encoded Message : 10010100011001101010110001101011001100101101110101011011100110001110001100011101001111101000110010111110110000001100101111101100001011111110100010010110000011010001111101010110001000011001100010111110101111111001111111010110011000110001011001001011001011011000010110000000010001101000111100111100101100110100101100010010111111101101100110110011000011100111110001101100011101000010110010011001001100
Decoded Message : Hi, people! This is string message from Binary Huffman Tree
########### showAll (BEGIN) ###########
        ===== Test#4 : Creating Dried Binary Huffman Tree from <int>-weights vector (Fibonacci sequence) =====


        -> This is Binary Huffman Coding <-
        Alphabet size           = 23
        Shortest code size      = 1
        Longest code size       = 22

        Weights sum             = 75024
        Average weight          = 3261

        Code-sizes sum          = 275
        Average code-size       = 11.9565

        Weighted code-sizes sum = 196391
        Ave. weighted code-size = 8538




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol      Code
      ------   ------   ----
           1   Symbol#01   0000000000000000000000
           1   Symbol#02   0000000000000000000001
           2   Symbol#03   000000000000000000001
           3   Symbol#04   00000000000000000001
           5   Symbol#05   0000000000000000001
           8   Symbol#06   000000000000000001
          13   Symbol#07   00000000000000001
          21   Symbol#08   0000000000000001
          34   Symbol#09   000000000000001
          55   Symbol#10   00000000000001
          89   Symbol#11   0000000000001
         144   Symbol#12   000000000001
         233   Symbol#13   00000000001
         377   Symbol#14   0000000001
         610   Symbol#15   000000001
         987   Symbol#16   00000001
        1597   Symbol#17   0000001
        2584   Symbol#18   000001
        4181   Symbol#19   00001
        6765   Symbol#20   0001
       10946   Symbol#21   001
       17711   Symbol#22   01
       28657   Symbol#23   1


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol      Code
      ------   ------   ----
           1   Symbol#01   0000000000000000000000
           1   Symbol#02   0000000000000000000001
           2   Symbol#03   000000000000000000001
           3   Symbol#04   00000000000000000001
           5   Symbol#05   0000000000000000001
           8   Symbol#06   000000000000000001
          13   Symbol#07   00000000000000001
          21   Symbol#08   0000000000000001
          34   Symbol#09   000000000000001
          55   Symbol#10   00000000000001
          89   Symbol#11   0000000000001
         144   Symbol#12   000000000001
         233   Symbol#13   00000000001
         377   Symbol#14   0000000001
         610   Symbol#15   000000001
         987   Symbol#16   00000001
        1597   Symbol#17   0000001
        2584   Symbol#18   000001
        4181   Symbol#19   00001
        6765   Symbol#20   0001
       10946   Symbol#21   001
       17711   Symbol#22   01
       28657   Symbol#23   1


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol      Code
      ------   ------   ----
       28657   Symbol#23   1
       17711   Symbol#22   01
       10946   Symbol#21   001
        6765   Symbol#20   0001
        4181   Symbol#19   00001
        2584   Symbol#18   000001
        1597   Symbol#17   0000001
         987   Symbol#16   00000001
         610   Symbol#15   000000001
         377   Symbol#14   0000000001
         233   Symbol#13   00000000001
         144   Symbol#12   000000000001
          89   Symbol#11   0000000000001
          55   Symbol#10   00000000000001
          34   Symbol#09   000000000000001
          21   Symbol#08   0000000000000001
          13   Symbol#07   00000000000000001
           8   Symbol#06   000000000000000001
           5   Symbol#05   0000000000000000001
           3   Symbol#04   00000000000000000001
           2   Symbol#03   000000000000000000001
           1   Symbol#01   0000000000000000000000
           1   Symbol#02   0000000000000000000001


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol      Code
      ------   ------   ----
           1   Symbol#01   0000000000000000000000
           1   Symbol#02   0000000000000000000001
           2   Symbol#03   000000000000000000001
           3   Symbol#04   00000000000000000001
           5   Symbol#05   0000000000000000001
           8   Symbol#06   000000000000000001
          13   Symbol#07   00000000000000001
          21   Symbol#08   0000000000000001
          34   Symbol#09   000000000000001
          55   Symbol#10   00000000000001
          89   Symbol#11   0000000000001
         144   Symbol#12   000000000001
         233   Symbol#13   00000000001
         377   Symbol#14   0000000001
         610   Symbol#15   000000001
         987   Symbol#16   00000001
        1597   Symbol#17   0000001
        2584   Symbol#18   000001
        4181   Symbol#19   00001
        6765   Symbol#20   0001
       10946   Symbol#21   001
       17711   Symbol#22   01
       28657   Symbol#23   1

########### showAll (END) #############
########### showAll (BEGIN) ###########
        ===== Test#5 : Creating Dried Binary Huffman Tree from <int>-weights file =====


        -> This is Binary Huffman Coding <-
        Alphabet size           = 9
        Shortest code size      = 1
        Longest code size       = 6

	Weights sum 		= 174
	Average weight 		= 19

        Code-sizes sum          = 36
        Average code-size       = 4

	Weighted code-sizes sum = 372
	Ave. weighted code-size = 41




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol     Code
      ------   ------   ----
           3   Symbol#1   000001
           3   Symbol#2   00001
          20   Symbol#3   011
           9   Symbol#4   0001
           2   Symbol#5   000000
           9   Symbol#6   0100
         100   Symbol#7   1
          11   Symbol#8   0101
          17   Symbol#9   001


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol     Code
      ------   ------   ----
           2   Symbol#5   000000
           3   Symbol#1   000001
           3   Symbol#2   00001
           9   Symbol#4   0001
          17   Symbol#9   001
           9   Symbol#6   0100
          11   Symbol#8   0101
          20   Symbol#3   011
         100   Symbol#7   1


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol     Code
      ------   ------   ----
         100   Symbol#7   1
          17   Symbol#9   001
          20   Symbol#3   011
           9   Symbol#4   0001
           9   Symbol#6   0100
          11   Symbol#8   0101
           3   Symbol#2   00001
           2   Symbol#5   000000
           3   Symbol#1   000001


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol     Code
      ------   ------   ----
           2   Symbol#5   000000
           3   Symbol#1   000001
           3   Symbol#2   00001
           9   Symbol#4   0001
           9   Symbol#6   0100
          11   Symbol#8   0101
          17   Symbol#9   001
          20   Symbol#3   011         100   Symbol#7   1

########### showAll (END) #############
########### showAll (BEGIN) ###########
        ===== Test#6 : Creating Loaded Binary Huffman Tree from <char, int>-data file =====


        -> This is Binary Huffman Coding <-
        Alphabet size           = 9
        Shortest code size      = 1
        Longest code size       = 6

	Weights sum 		= 174
	Average weight 		= 19

        Code-sizes sum          = 36
        Average code-size       = 4

	Weighted code-sizes sum = 372
	Ave. weighted code-size = 41




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol   Code
      ------   ------   ----
           3   a        000001
           3   b        00001
          20   c        011
           9   d        0001
           2   e        000000
           9   f        0100
         100   h        1
          11   x        0101
          17   y        001


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol   Code
      ------   ------   ----
           2   e        000000
           3   a        000001
           3   b        00001
           9   d        0001
          17   y        001
           9   f        0100
          11   x        0101
          20   c        011
         100   h        1


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol   Code
      ------   ------   ----
         100   h        1
          17   y        001
          20   c        011
           9   d        0001
           9   f        0100
          11   x        0101
           3   b        00001
           2   e        000000
           3   a        000001


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol   Code
      ------   ------   ----
           2   e        000000
           3   a        000001
           3   b        00001
           9   d        0001
           9   f        0100
          11   x        0101
          17   y        001
          20   c        011
         100   h        1

########### showAll (END) #############
########### showAll (BEGIN) ###########
        ===== Test#7 : Creating Loaded Binary Huffman Tree from <string, float>-data vector =====


        -> This is Binary Huffman Coding <-
        Alphabet size           = 8
        Shortest code size      = 1
        Longest code size       = 6

        Weights sum             = 0.0586
        Average weight          = 0.007325

        Code-sizes sum          = 33
        Average code-size       = 4.125

        Weighted code-sizes sum = 0.1284
        Ave. weighted code-size = 0.01605




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol           Code
      ------   ------   ----
      0.0022   a1               00010
       0.002   aa22             00001
        0.02   aaa333           01
       0.007   bbyy22           001
      0.0001   bx1              000000
       0.023   ccczzzzzzzz333   1
       0.003   cczzzzz22        00011
      0.0013   czzz1            000001


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol           Code
      ------   ------   ----
      0.0001   bx1              000000
      0.0013   czzz1            000001
       0.002   aa22             00001
      0.0022   a1               00010
       0.003   cczzzzz22        00011
       0.007   bbyy22           001
        0.02   aaa333           01
       0.023   ccczzzzzzzz333   1


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol           Code
      ------   ------   ----
       0.023   ccczzzzzzzz333   1
        0.02   aaa333           01
       0.007   bbyy22           001
       0.002   aa22             00001
      0.0022   a1               00010
       0.003   cczzzzz22        00011
      0.0001   bx1              000000
      0.0013   czzz1            000001


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol           Code
      ------   ------   ----
      0.0001   bx1              000000
      0.0013   czzz1            000001
       0.002   aa22             00001
      0.0022   a1               00010
       0.003   cczzzzz22        00011
       0.007   bbyy22           001
        0.02   aaa333           01
       0.023   ccczzzzzzzz333   1

########### showAll (END) #############
########### showAll (BEGIN) ###########
        ===== Test#8 : Creating Loaded Binary Huffman Tree from <AAA, BBB>-data vector =====


        -> This is Binary Huffman Coding <-
        Alphabet size           = 5
        Shortest code size      = 2
        Longest code size       = 3

        Weights sum             = BBB_41
        Average weight          = BBB_44

        Code-sizes sum          = 12
        Average code-size       = 2.4

	Weighted code-sizes sum = BBB_46
	Ave. weighted code-size = BBB_59




        =======================
        Symbols and their codes
         -> Sorted by Symbol
        =======================
      Weight   Symbol   Code
      ------   ------   ----
       BBB_1   AAA_1    00
       BBB_2   AAA_2    101
       BBB_3   AAA_3    11
       BBB_4   AAA_4    01
       BBB_5   AAA_5    100


        =========================
        Codes and their symbols
         -> Lexico-Sorted by Code
        =========================
      Weight   Symbol   Code
      ------   ------   ----
       BBB_1   AAA_1    00
       BBB_4   AAA_4    01
       BBB_5   AAA_5    100
       BBB_2   AAA_2    101
       BBB_3   AAA_3    11


        =======================
        Codes and their symbols
         -> Sorted by Code Size
        =======================
      Weight   Symbol   Code
      ------   ------   ----
       BBB_1   AAA_1    00
       BBB_4   AAA_4    01
       BBB_5   AAA_5    11
       BBB_2   AAA_2    100
       BBB_3   AAA_3    101


        =======================
        Codes and their symbols
         -> Sorted by Weight
        =======================
      Weight   Symbol   Code
      ------   ------   ----
       BBB_5   AAA_5    100
       BBB_2   AAA_2    101
       BBB_1   AAA_1    00
       BBB_4   AAA_4    01
       BBB_3   AAA_3    11

########### showAll (END) #############
//------------------- Running Results : END ---------------

====================================================
===================== 8. Download ==================
//#########################################################

http://sourceforge.net/projects/huffman-ta/
http://alexvn.freeservers.com/s1/zip_dir/huffman_ta.zip

http://www.simtel.net/pub/pd/60300.shtml       
http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=3511&lngWId=3       
http://home.barak-online.net/alexvn/s2/hf/hufnta22.zip 


http://groups.google.com/groups?th=f9bb13f7426e888c  (Source)
http://groups.google.com/groups?th=7daf90d4f66a47ad  (Raw run log - Demo)