-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
#include "huffman.h"
#include "common.h"
namespace huffman {
struct node {
char c; int f; node * l, * r;
node(char _c, int _f) { c = _c, f = _f, l = r = NULL; }
};
struct comp { bool operator()(node * a, node * b) { return a->f > b->f; } };
node * root;
vector<bool> path;
vector<vector<bool>> code(128);
void traverse(node * n) {
if (n->l) {
path.push_back(0);
traverse(n->l);
path.pop_back();
}
if (n->r) {
path.push_back(1);
traverse(n->r);
path.pop_back();
}
if (n->c) code[n->c] = path;
}
void encode_tree(node * n, vector<bool> & v) {
if (n->c) {
v.push_back(1);
for (int i = 0; i < 8; ++i) v.push_back(1 & (n->c >> i));
}
else {
v.push_back(0);
if (n->l) {
v.push_back(1);
encode_tree(n->l, v);
}
else v.push_back(0);
if (n->r) {
v.push_back(1);
encode_tree(n->r, v);
}
else v.push_back(0);
}
}
int idx = 0;
void decode_tree(node * n, vector<bool> & v) {
if (v[idx++] == 1) {
for (int i = 0; i < 8; ++i) n->c |= (1 << v[idx++]);
}
else {
if (v[idx++] == 1) {
n->l = new node(0, 0);
decode_tree(n->l, v);
}
if (v[idx++] == 1) {
n->r = new node(0, 0);
decode_tree(n->r, v);
}
}
}
void generate(vector<int> f) {
priority_queue<node *, vector<node *>, comp> pq;
for (int c = 0; c < 128; ++c) {
node * n = new node(c, f[c]);
pq.push(n);
}
while (pq.size() > 1) {
node * l = pq.top(); pq.pop();
node * r = pq.top(); pq.pop();
node * n = new node(0, l->f + r->f);
n->l = l, n->r = r;
pq.push(n);
}
root = pq.top();
}
void solve(node * n, vector<bool> & v, string & s) {
if (n->c) {
s += n->c;
//cout << (int)n->c << '\n';
if (idx > v.size()) return;
solve(root, v, s);
}
else {
if (v[idx++] == 0) solve(n->l, v, s);
else solve(n->r, v, s);
}
}
vector<bool> encode(string s) {
vector<int> f(128, 0);
for (auto& c : s) ++f[c];
generate(f);
traverse(root);
vector<bool> ret;
encode_tree(root, ret);
for (auto& c : s) {
for (auto b : code[c]) ret.push_back(b);
}
return ret;
}
string decode(vector<bool> v) {
root = new node(0, 0);
decode_tree(root, v);
string ret;
solve(root, v, ret);
return ret;
}
}