#include "stdio.h" #include #include // for CHAR_BIT #include #include #include #include #include using namespace std; const int UniqueSymbols = 1 << CHAR_BIT; void printBits(unsigned int val, int numbits) { for (int i = numbits - 1; i >= 0; i--) putchar('0' + ((val >> i) & 1)); } typedef vector HuffCode; typedef map 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(unsigned int (&frequencies)[UniqueSymbols]) { std::priority_queue, 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(node)) { outCodes[lf->c] = prefix; } else if (const InternalNode *in = dynamic_cast(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); } }