AlgoPlus v0.1.0
Loading...
Searching...
No Matches
huffman_encoding.h
1#ifndef HUFFMAN_ENCODING_H
2#define HUFFMAN_ENCODING_H
3
4#ifdef __cplusplus
5#include <cassert>
6#include <iostream>
7#include <memory>
8#include <queue>
9#include <string>
10#include <type_traits>
11#include <unordered_map>
12#include <vector>
13#endif
14
18class huffman {
19 private:
20 struct node {
21 double weight;
22 std::string ID;
23 std::shared_ptr<node> left;
24 std::shared_ptr<node> right;
25 node(std::string ID, double weight)
26 : ID(ID), weight(weight), left(nullptr), right(nullptr) {}
27 };
28 double _size{};
29 int64_t MAX_DEPTH;
30 std::shared_ptr<node> root;
31 std::unordered_map<char, double> appearances;
32 std::priority_queue<std::pair<double, std::shared_ptr<node>>,
33 std::vector<std::pair<double, std::shared_ptr<node>>>,
34 std::greater<std::pair<double, std::shared_ptr<node>>>>
35 _weights;
36 std::unordered_map<char, double> map_weights;
37
38 public:
45 explicit huffman(std::vector<std::string> v = {}, int64_t MAX_DEPTH = 10)
46 : root(nullptr), MAX_DEPTH(MAX_DEPTH) {
47 for (std::string& x : v) {
48 for (char& y : x) {
49 appearances[y]++;
50 _size++;
51 }
52 }
53 }
54
59 inline void create_tree() {
60 compute_weights();
61 while (_weights.size() != 1) {
62 auto first_node = _weights.top();
63 _weights.pop();
64 auto second_node = _weights.top();
65 _weights.pop();
66 std::shared_ptr<node> nn =
67 std::make_shared<node>(first_node.second->ID + second_node.second->ID,
68 first_node.first + second_node.first);
69 nn->right = second_node.second;
70 nn->left = first_node.second;
71 _weights.push({nn->weight, nn});
72 }
73 root = _weights.top().second;
74 }
75
80 inline std::unordered_map<std::string, std::string> decode() {
81 std::vector<int> v(MAX_DEPTH);
82 int top = 0;
83 std::unordered_map<std::string, std::string> decoded;
84 _decode(root, v, top, decoded);
85 return decoded;
86 }
87
88 private:
89 void compute_weights() {
90 for (auto& x : appearances) {
91 std::string curr = "";
92 curr += x.first;
93 std::shared_ptr<node> nn = std::make_shared<node>(curr, x.second / _size);
94 _weights.push({x.second / _size, nn});
95 map_weights[x.first] = x.second / _size;
96 }
97 }
98
99 void _decode(std::shared_ptr<node> root, std::vector<int> arr, int top,
100 std::unordered_map<std::string, std::string>& decoded) {
101 if (root->left) {
102 arr[top] = 0;
103 _decode(root->left, arr, top + 1, decoded);
104 }
105 if (root->right) {
106 arr[top] = 1;
107 _decode(root->right, arr, top + 1, decoded);
108 }
109 if (!root->left && !root->right) {
110 std::string ans = "";
111 for (int i = 0; i < top; i++) {
112 ans += std::to_string(arr[i]);
113 }
114 decoded[root->ID] = ans;
115 }
116 }
117};
118
119#endif
void create_tree()
create_tree function creates the tree in recursive fashion, from the leafs up to the root
Definition huffman_encoding.h:59
huffman(std::vector< std::string > v={}, int64_t MAX_DEPTH=10)
constructor for huffman class
Definition huffman_encoding.h:45
std::unordered_map< std::string, std::string > decode()
decode function
Definition huffman_encoding.h:80