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 intNode *in = dynamic_cast<const intNode*>(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); } }
void generateCodes(Node* root, std::map<char, std::pair<char, std::uint16_t>>& codes, char size = 0, std::uint16_t value = 0) { if (!root->left && !root->right) { // it is a leaf assert(root->symbol != 'n'); assert(root->symbol != 'e'); codes[root->symbol] = {size, value}; } else { value <<= 1; ++size; if (root->left) { generateCodes(root->left, codes, size, value); } if (root->right) { generateCodes(root->right, codes, size, value + 1); } } }
/*--------------------------------------------------------------------- Recurse through the tree in depth first order, and collect the list of bits as a path from the root (where 0 means left branch, and 1 means right). Whenever a leaf is hit, store the path of bits as its code. ---------------------------------------------------------------------*/ void Huffman::generateCodes(const ByteData* node, std::string prefix) const { if(root->getValue().getData() != NIL) { root->setCode("0"); lookupList[0].setCode("0"); return; } if(node->getLeftNode() != 0) generateCodes(node->getLeftNode(), prefix + "0"); node->setCode(prefix); if(node->getValue().getData() != NIL) lookupList[node->getValue().getData()].setCode(node->getCode().c_str()); if(node->getRightNode() != 0) generateCodes(node->getRightNode(), prefix + "1"); }
void HuffmanStringProcessor::generateCodes(BitStream& rBS, S32 index, S32 depth) { if (index < 0) { // leaf node, copy the code in, and back out... HuffLeaf& rLeaf = mHuffLeaves[-(index + 1)]; memcpy(&rLeaf.code, rBS.getBuffer(), sizeof(rLeaf.code)); rLeaf.numBits = depth; } else { HuffNode& rNode = mHuffNodes[index]; S32 pos = rBS.getBitPosition(); rBS.writeFlag(false); generateCodes(rBS, rNode.index0, depth + 1); rBS.setBitPosition(pos); rBS.writeFlag(true); generateCodes(rBS, rNode.index1, depth + 1); rBS.setBitPosition(pos); } }
int main() { std::string input((std::istreambuf_iterator<char>(std::cin)), std::istreambuf_iterator<char>()); std::map<char, unsigned> data; for (char c : input) { ++data[c]; } Node* root = createTree(data); std::map<char, std::pair<char, std::uint16_t>> codes; generateCodes(root, codes); std::string tree = mapToString(codes); std::cout << tree; }
int main(){ 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; }
void HuffmanStringProcessor::buildTables() { TNLAssert(mTablesBuilt == false, "Cannot build tables twice!"); mTablesBuilt = true; S32 i; // First, construct the array of wraps... // mHuffLeaves.resize(256); mHuffNodes.reserve(256); mHuffNodes.resize(mHuffNodes.size() + 1); for (i = 0; i < 256; i++) { HuffLeaf& rLeaf = mHuffLeaves[i]; rLeaf.pop = mCharFreqs[i] + 1; rLeaf.symbol = U8(i); memset(&rLeaf.code, 0, sizeof(rLeaf.code)); rLeaf.numBits = 0; } S32 currWraps = 256; HuffWrap* pWrap = new HuffWrap[256]; for (i = 0; i < 256; i++) { pWrap[i].set(&mHuffLeaves[i]); } while (currWraps != 1) { U32 min1 = 0xfffffffe, min2 = 0xffffffff; S32 index1 = -1, index2 = -1; for (i = 0; i < currWraps; i++) { if (pWrap[i].getPop() < min1) { min2 = min1; index2 = index1; min1 = pWrap[i].getPop(); index1 = i; } else if (pWrap[i].getPop() < min2) { min2 = pWrap[i].getPop(); index2 = i; } } TNLAssert(index1 != -1 && index2 != -1 && index1 != index2, "hrph"); // Create a node for this... mHuffNodes.resize(mHuffNodes.size() + 1); HuffNode& rNode = mHuffNodes.last(); rNode.pop = pWrap[index1].getPop() + pWrap[index2].getPop(); rNode.index0 = determineIndex(pWrap[index1]); rNode.index1 = determineIndex(pWrap[index2]); S32 mergeIndex = index1 > index2 ? index2 : index1; S32 nukeIndex = index1 > index2 ? index1 : index2; pWrap[mergeIndex].set(&rNode); if (index2 != (currWraps - 1)) { pWrap[nukeIndex] = pWrap[currWraps - 1]; } currWraps--; } TNLAssert(currWraps == 1, "wrong wraps?"); TNLAssert(pWrap[0].pNode != NULL && pWrap[0].pLeaf == NULL, "Wrong wrap type!"); // Ok, now we have one wrap, which is a node. we need to make sure that this // is the first node in the node list. mHuffNodes[0] = *(pWrap[0].pNode); delete [] pWrap; U32 code = 0; BitStream bs((U8 *) &code, 4); generateCodes(bs, 0, 0); }
/** * Constructs a huffmanTree object for input frequencies vector * @param _input Input vector of frequencies to be encoded * @throws std::exception in case of a member initialisztion or tree building failed */ explicit huffmanTree_t(const std::vector<std::size_t> &_input): m_tree(_input.size()) { std::shared_ptr<node_t> tree; buildTree(_input, tree); generateCodes(tree, huffmanCode_t(), huffmanPoint_t()); }