📄 huffman_template_algorithm.html
字号:
//==========================================
if (!((mapSymbols_.insert (Node_MAP_SYMBOLS::value_type (cur_symbol, cur_weight))).second))
{
ASSERT (0);
}
//==========================================
}
} // void InternalNode<SYMBOL, WEIGHT>::addNode(
<a NAME="label_TerminalNode_method"></a>
//#######################################################
//##### PART : template class <b><a href="#label_TerminalNode_class">TerminalNode</a></b> ##############
//############ <font color="FF7733"><b>Methods</b></font> ##################################
//#######################################################
//-----------------------
// 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
<a NAME="label_BasicHuffmanTree_method"></a>
//#######################################################
//##### PART : template class <b><a href="#label_BasicHuffmanTree_class">BasicHuffmanTree</a></b> ##########
//############ <font color="FF7733"><b>Methods</b></font> ##################################
//#######################################################
//-----------------------
// 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, WEIG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -