#include "HuffmanEncoder.h" #include "RawTree.h" #include #include #include #include void HuffmanEncoder::dumpNode(RawNode* node, unsigned depth) const { if (!node) { return; } auto data = node->getData(); std::string prefix(depth, '_'); if (node->isLeaf()) { std::cout << prefix << "Leaf with value: " << data.first << " and sum " << data.second << std::endl; } else { std::cout << prefix << "Intermediate with sum " << data.second << std::endl; std::cout << prefix << "Doing Left.." << std::endl; dumpNode(node->getLeftChild(), depth+1); std::cout << prefix << "Doing Right.." << std::endl; dumpNode(node->getRightChild(), depth+1); std::cout << prefix << "*****" << std::endl; } } void HuffmanEncoder::dumpTree(const RawTree& tree) const { dumpNode(tree.getRootNode(), 0); } void HuffmanEncoder::encode(const HuffmanEncoder::DataStream& stream) { std::unordered_map counts; for (auto c : stream) { counts[c]++; } encode(counts); } void HuffmanEncoder::encode(const std::unordered_map& counts) { std::cout << "Counts" << std::endl; for (const auto& data: counts) { std::cout << data.first << " | " << data.second << std::endl; } std::cout << "*******" << std::endl; auto cmp = [](RawNode* left, RawNode* right) { return left->getData().second > right->getData().second; }; std::priority_queue*, std::vector* >, decltype(cmp)> q(cmp); for (const auto& entry : counts) { q.push(new RawNode(entry)); } while(q.size() > 1) { auto node0 = q.top(); q.pop(); auto node1 = q.top(); q.pop(); const auto sum = node0->getData().second + node1->getData().second; auto new_node = new RawNode(CountPair{0, sum}); new_node->addChild(node0); new_node->addChild(node1); q.push(new_node); } auto root = q.top(); q.pop(); RawTree tree; tree.addRootNode(root); //using TableEntry = std::tuple<> dumpTree(tree); std::cout << "********" << std::endl; }