Huffman encoding

#include <iostream>
#include <queue>
#include <map>
#include <climits> // for CHAR_BIT
#include <iterator>
#include <algorithm>

const int UniqueSymbols = 1 << CHAR_BIT;
const char* SampleString = "this is an example for huffman encoding";

typedef std::vector<bool> HuffCode;
typedef std::map<char, HuffCode> HuffCodeMap;

class INode
{
public:
 const int f;

 virtual ~INode() {}

protected:
 INode(int f) : f(f) {}
};

class InternalNode : public INode
{
public:
 INode *const left;
 INode *const right;

 InternalNode(INode* c0, INode* c1) : INode(c0->f + c1->f), left(c0), right(c1) {}
 ~InternalNode()
 {
  delete left;
  delete right;
 }
};

class LeafNode : public INode
{
public:
 const char c;

 LeafNode(int f, char c) : INode(f), c(c) {}
};

struct NodeCmp
{
 bool operator()(const INode* lhs, const INode* rhs) const { return lhs->f > rhs->f; }
};

INode* BuildTree(const int (&frequencies)[UniqueSymbols])
{
 std::priority_queue<INode*, std::vector<INode*>, NodeCmp> trees;

 for (int i = 0; i < UniqueSymbols; ++i)
 {
  if(frequencies[i] != 0)
  trees.push(new LeafNode(frequencies[i], (char)i));
 }
 while (trees.size() > 1)
 {
  INode* childR = trees.top();
  trees.pop();

  INode* childL = trees.top();
  trees.pop();

  INode* parent = new InternalNode(childR, childL);
  trees.push(parent);
 }
 return trees.top();
}

void GenerateCodes(const INode* node, const HuffCode& prefix, HuffCodeMap& outCodes)
{
 if (const LeafNode* lf = dynamic_cast<const LeafNode*>(node))
 {
  outCodes[lf->c] = prefix;
 }
 else if (const InternalNode* in = dynamic_cast<const InternalNode*>(node))
 {
  HuffCode leftPrefix = prefix;
  leftPrefix.push_back(false);
  GenerateCodes(in->left, leftPrefix, outCodes);

  HuffCode rightPrefix = prefix;
  rightPrefix.push_back(true);
  GenerateCodes(in->right, rightPrefix, outCodes);
 }
}

int main()
{
 // Build frequency table
 int frequencies[UniqueSymbols] = {0};
 const char* ptr = SampleString;
 while (*ptr != '\0')
 ++frequencies[*ptr++];

 INode* root = BuildTree(frequencies);

 HuffCodeMap codes;
 GenerateCodes(root, HuffCode(), codes);
 delete root;

 for (HuffCodeMap::const_iterator it = codes.begin(); it != codes.end(); ++it)
 {
  std::cout << it->first << " ";
  std::copy(it->second.begin(), it->second.end(),
  std::ostream_iterator<bool>(std::cout));
  std::cout << std::endl;
 }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值