哈夫曼编码的设计与实现
来源:互联网 发布:党员干部知敬畏 编辑:程序博客网 时间:2024/06/05 18:39
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
const static int nBufferSize = 1024;
char g_szBuffer[ nBufferSize] = "ABCEFHDILASJBNDBBBBSAAUILDK" ;
int g_nMaxNum = 100000;
enum { TREE_TAG_LEFT = 0, TREE_TAG_RIGHT = 1, };
struct SBinaryTreeNode
{
char cByte ;
int nValue ;
bool bTakeTag ;
SBinaryTreeNode* pParent ;
SBinaryTreeNode* pLeftChild ;
SBinaryTreeNode* pRightChild ;
};
struct SByteCoding
{
char cByte ;
std::list <int> listByteCodes;
};
// ===========================================================================================================================
// 仿函数
// ===========================================================================================================================
struct SFindByte
{
SFindByte( char byte ): cByte( byte ) { }
bool operator () ( SBinaryTreeNode* pNodeInfo )
{
if( pNodeInfo && pNodeInfo-> cByte == cByte )
return true ;
return false ;
}
private :
char cByte ;
};
struct SFindByteFormCodings
{
SFindByteFormCodings ( char byte ): cByte ( byte ) { }
bool operator () ( SByteCoding* pFindByte )
{
if( pFindByte && pFindByte-> cByte == cByte )
return true ;
return false ;
}
private :
char cByte ;
};
// ===========================================================================================================================
// 仿函数
// ===========================================================================================================================
int _tmain( int argc , _TCHAR* argv[])
{
std::vector <SBinaryTreeNode*> vecBinaryNode;
vecBinaryNode.clear ();
std::vector <SBinaryTreeNode*>:: iterator iVecTreeNode ;
char c ;
for( int i = 0; i < nBufferSize && g_szBuffer[ i] != '/0'; ++i )
{
c = g_szBuffer [i];
iVecTreeNode = std ::find_if( vecBinaryNode .begin(), vecBinaryNode.end (), SFindByte( c ) );
if( iVecTreeNode == vecBinaryNode. end() )
{
SBinaryTreeNode* pBinaryNode = new SBinaryTreeNode ;
if( !pBinaryNode )
{
std::cout <<"Error 3"<< std::endl ;
system( "pause" );
return 0;
}
pBinaryNode->pLeftChild = NULL;
pBinaryNode->pRightChild = NULL;
pBinaryNode->pParent = NULL;
pBinaryNode->cByte = c;
pBinaryNode->nValue = 1;
pBinaryNode->bTakeTag = false;
vecBinaryNode.push_back ( pBinaryNode );
}
else
{
SBinaryTreeNode* pExistNode = (*iVecTreeNode );
if( !pExistNode )
{
std::cout <<"Error 4"<< std::endl ;
system( "pause" );
return 0;
}
++ pExistNode->nValue ;
}
}
// 通过vecBinaryNode 搭建哈夫曼树
int nMinValue , nSecMinValue;
int nByteNum = vecBinaryNode. size();
for( int i = 1; i <= nByteNum - 1; ++i ) // nSize - 1 次合并两个顶点
{
SBinaryTreeNode* pMinValueNode = NULL;
SBinaryTreeNode* pSecondMinValueNode = NULL;
nMinValue = g_nMaxNum - 1;
nSecMinValue = g_nMaxNum ;
std::vector <SBinaryTreeNode*>:: iterator iVecBegin = vecBinaryNode. begin();
std::vector <SBinaryTreeNode*>:: iterator iVecEnd = vecBinaryNode .end();
for( ; iVecBegin != iVecEnd; ++ iVecBegin )
{
SBinaryTreeNode* pNowBinary = (*iVecBegin);
if( !pNowBinary )
{
std::cout <<"Error 5"<< std::endl ;
system( "pause" );
return 0;
}
if( true == pNowBinary-> bTakeTag )
continue;
if( pNowBinary ->nValue < nMinValue )
{
pSecondMinValueNode = pMinValueNode ;
pMinValueNode = pNowBinary;
nSecMinValue = nMinValue ;
nMinValue = pNowBinary-> nValue;
}
else if ( pNowBinary-> nValue >= nMinValue && pNowBinary ->nValue < nSecMinValue )
{
pSecondMinValueNode = pNowBinary ;
nSecMinValue = pNowBinary ->nValue;
}
}
if( !pMinValueNode || !pSecondMinValueNode )
{
std::cout <<"Error 6"<< std::endl ;
system( "pause" );
return 0;
}
SBinaryTreeNode* pConnectionNode = new SBinaryTreeNode ;
if( !pConnectionNode )
{
std::cout <<"Error 7"<< std::endl ;
system( "pause" );
return 0;
}
pMinValueNode->bTakeTag = true;
pMinValueNode->pParent = pConnectionNode;
pSecondMinValueNode->bTakeTag = true;
pSecondMinValueNode->pParent = pConnectionNode;
pConnectionNode->bTakeTag = false;
pConnectionNode->cByte = 0;
pConnectionNode->nValue = pMinValueNode ->nValue + pSecondMinValueNode->nValue ;
pConnectionNode->pLeftChild = pMinValueNode;
pConnectionNode->pRightChild = pSecondMinValueNode ;
pConnectionNode->pParent = NULL;
vecBinaryNode.push_back ( pConnectionNode );
}
// 求哈夫曼树的编码 同时求其跟结点
std::vector <SByteCoding*> vecByteCoding;
vecByteCoding.clear ();
SBinaryTreeNode* pBinaryTreeRoot = NULL;
std::vector <SBinaryTreeNode*>:: iterator iVecTreeBegin = vecBinaryNode. begin();
std::vector <SBinaryTreeNode*>:: iterator iVecTreeEnd = vecBinaryNode .end();
for( ; iVecTreeBegin != iVecTreeEnd; ++ iVecTreeBegin )
{
SBinaryTreeNode* pFindLeafCodes = (*iVecTreeBegin );
if( !pFindLeafCodes )
{
std::cout <<"Error 8"<< std::endl ;
system( "pause" );
return 0;
}
if( 0 != pFindLeafCodes ->cByte )
{
SByteCoding* pByteCoding = new SByteCoding;
if( !pByteCoding )
{
std::cout <<"Error 9"<< std::endl ;
system( "pause" );
return 0;
}
pByteCoding->cByte = pFindLeafCodes-> cByte;
pByteCoding->listByteCodes .clear();
while(1)
{
if( pFindLeafCodes ->pParent != NULL )
{
if( pFindLeafCodes ->pParent-> pLeftChild == pFindLeafCodes )
pByteCoding->listByteCodes .push_front( TREE_TAG_LEFT );
else if ( pFindLeafCodes ->pParent-> pRightChild == pFindLeafCodes )
pByteCoding->listByteCodes .push_front( TREE_TAG_RIGHT );
pFindLeafCodes = pFindLeafCodes ->pParent;
}
else
{
if( NULL == pBinaryTreeRoot )
pBinaryTreeRoot = pFindLeafCodes ;
break;
}
}
vecByteCoding.push_back ( pByteCoding );
}
}
// 输出编码格式 std::vector<SByteCoding*> vecByteCoding;
std::vector <SByteCoding*>:: iterator iVecCodingBegin = vecByteCoding .begin();
std::vector <SByteCoding*>:: iterator iVecCodingEnd = vecByteCoding .end();
for( ; iVecCodingBegin != iVecCodingEnd; ++iVecCodingBegin )
{
SByteCoding* pPrintByteCoding = (*iVecCodingBegin );
if( !pPrintByteCoding )
{
std::cout <<"Error 10"<<std ::endl;
system( "pause" );
return 0;
}
std::cout <<" Byte --->"<< pPrintByteCoding->cByte <<" Coding --->";
std::list <int>:: iterator ilistBegin = pPrintByteCoding ->listByteCodes. begin();
std::list <int>:: iterator ilistEnd = pPrintByteCoding ->listByteCodes. end();
for( ; ilistBegin != ilistEnd; ++ ilistBegin )
std::cout <<(*ilistBegin);
std::cout <<std:: endl<<std ::endl;
}
// 将g_szBuffer[nBufferSize] 编码
// 将编码完的编码串用 list 容器存起来
std::list <int> listBufferCodes;
listBufferCodes.clear ();
std::vector <SByteCoding*>:: iterator iVecFindCodes ;
for( int i = 0; i < nBufferSize && g_szBuffer[ i] != '\0'; ++i )
{
char cByte = g_szBuffer[ i]; // SFindByteFormCodings
iVecFindCodes = std ::find_if( vecByteCoding .begin(), vecByteCoding.end (), SFindByteFormCodings ( cByte ) );
if( iVecFindCodes == vecByteCoding. end() )
{
std::cout <<"Error 11"<<std ::endl;
system( "pause" );
return 0;
}
std::list <int>:: iterator ilistBegin = (*iVecFindCodes )->listByteCodes. begin();
std::list <int>:: iterator ilistEnd = (*iVecFindCodes )->listByteCodes. end();
for( ; ilistBegin != ilistEnd; ++ ilistBegin )
listBufferCodes.push_back ( (*ilistBegin) );
}
// PrintCodes( listBufferCodes );
std::cout <<g_szBuffer<< " 编码: " ;
std::list <int>:: iterator ilistPrintCodesBegin = listBufferCodes .begin();
std::list <int>:: iterator ilistPrintCodesEnd = listBufferCodes .end();
for( ; ilistPrintCodesBegin != ilistPrintCodesEnd; ++ilistPrintCodesBegin )
std::cout <<(*ilistPrintCodesBegin);
std::cout <<std:: endl;
// 解码
std::vector <char> vecDecodeStr;
vecDecodeStr.clear ();
ilistPrintCodesBegin = listBufferCodes. begin();
ilistPrintCodesEnd = listBufferCodes .end();
SBinaryTreeNode* pFindNode = pBinaryTreeRoot;
for( ; ilistPrintCodesBegin != ilistPrintCodesEnd; ++ilistPrintCodesBegin )
{
int nTag = (*ilistPrintCodesBegin);
if( TREE_TAG_LEFT == nTag )
{
pFindNode = pFindNode ->pLeftChild;
}
else
pFindNode = pFindNode ->pRightChild;
if( pFindNode ->cByte != 0 )
{
char cNewByte = pFindNode-> cByte;
vecDecodeStr.push_back ( cNewByte );
pFindNode = pBinaryTreeRoot ;
}
}
// 输出解码
std::cout <<std:: endl<<" 解码 : ";
std::vector <char>:: iterator iVecCharBegin = vecDecodeStr .begin();
std::vector <char>:: iterator iVecCharEnd = vecDecodeStr .end();
for( ; iVecCharBegin != iVecCharEnd; ++ iVecCharBegin )
std::cout <<(*iVecCharBegin);
std::cout <<std:: endl;
system("pause" );
return 0;
}
- 哈夫曼编码的设计与实现
- 5.6哈夫曼编码的设计与实现
- 哈夫曼编码/译码的设计与实现
- 哈夫曼编码的设计与实现
- 范式Huffman编码的设计与实现
- 范式Huffman编码的设计与实现
- 数组编码和解码问题的求解设计与实现
- Atitit.Base64编码原理与实现设计
- 哈夫曼编码的原理与实现
- 哈夫曼编码与解码的JavaScript实现
- 通用的业务编码规则设计实现
- 通用的业务编码规则设计实现
- 设计与编码的时间平衡
- Huffman编码的设计与应用
- 用Flash cs3与flex 3让程序员与设计师分工协作以实现编码与设计分离的一种方法;
- 哈夫曼编码的实现
- 哈夫曼编码的实现
- 算法设计与分析--霍夫曼树编码(C++实现)
- MySQL触发器
- 如何编写Dll
- 剖析 Pexpect
- QImage 图像格式小结
- iOS录制音频
- 哈夫曼编码的设计与实现
- eclipse在Ubuntu 13.04下的安装过程及问题小记
- 怎样使用Markdown
- 需要学习的计划
- 常用正则表达式大全!
- 15款最佳免费SEO工具
- 插入排序
- fdisk
- Unity3d_qq互联共享_Oauth2.0