#include <iostream>
#include <queue>
#include <vector>
#include <string>
using namespace std;
struct Node {
char ch;
int freq;
Node *left, *right;
Node(char c, int f, Node* l = nullptr, Node* r = nullptr)
: ch(c), freq(f), left(l), right(r) {}
};
struct Compare {
bool operator()(Node* a, Node* b) {
return a->freq > b->freq;
}
};
void buildCodes(Node* root, string code, vector<pair<char,string>>& codes) {
if (!root) return;
if (!root->left && !root->right)
codes.push_back({root->ch, code});
buildCodes(root->left, code + "0", codes);
buildCodes(root->right, code + "1", codes);
}
string encode(string text, vector<pair<char,string>>& codes) {
string res;
for (char c : text)
for (auto &p : codes)
if (p.first == c)
res += p.second;
return res;
}
string decode(string s, Node* root) {
string res;
Node* cur = root;
for (char b : s) {
cur = (b == '0') ? cur->left : cur->right;
if (!cur->left && !cur->right) {
res += cur->ch;
cur = root;
}
}
return res;
}
void printDOT(Node* root) {
if (!root) return;
if (root->left) {
cout << "\"" << root->ch << root->freq << "\" -- \""
<< root->left->ch << root->left->freq << "\"\n";
printDOT(root->left);
}
if (root->right) {
cout << "\"" << root->ch << root->freq << "\" -- \""
<< root->right->ch << root->right->freq << "\"\n";
printDOT(root->right);
}
}
int main() {
string text = "cheprazovivan";
vector<Node*> nodes;
for (char c : text) {
bool found = false;
for (auto &n : nodes) {
if (n->ch == c) {
n->freq++;
found = true;
break;
}
}
if (!found)
nodes.push_back(new Node(c, 1));
}
priority_queue<Node*, vector<Node*>, Compare> pq;
for (auto n : nodes)
pq.push(n);
while (pq.size() > 1) {
Node* a = pq.top(); pq.pop();
Node* b = pq.top(); pq.pop();
pq.push(new Node('\0', a->freq + b->freq, a, b));
}
Node* root = pq.top();
vector<pair<char,string>> codes;
buildCodes(root, "", codes);
cout << "Коди Хаффмана:\n";
for (auto &p : codes)
cout << p.first << " : " << p.second << endl;
string enc = encode(text, codes);
cout << "\nENCODED:\n" << enc << endl;
cout << "\nDECODED:\n" << decode(enc, root) << endl;
cout << "\nDOT:\ngraph G {\n";
printDOT(root);
cout << "}\n";
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8cXVldWU+CiNpbmNsdWRlIDx2ZWN0b3I+CiNpbmNsdWRlIDxzdHJpbmc+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IE5vZGUgewogICAgY2hhciBjaDsKICAgIGludCBmcmVxOwogICAgTm9kZSAqbGVmdCwgKnJpZ2h0OwoKICAgIE5vZGUoY2hhciBjLCBpbnQgZiwgTm9kZSogbCA9IG51bGxwdHIsIE5vZGUqIHIgPSBudWxscHRyKQogICAgICAgIDogY2goYyksIGZyZXEoZiksIGxlZnQobCksIHJpZ2h0KHIpIHt9Cn07CgpzdHJ1Y3QgQ29tcGFyZSB7CiAgICBib29sIG9wZXJhdG9yKCkoTm9kZSogYSwgTm9kZSogYikgewogICAgICAgIHJldHVybiBhLT5mcmVxID4gYi0+ZnJlcTsKICAgIH0KfTsKCnZvaWQgYnVpbGRDb2RlcyhOb2RlKiByb290LCBzdHJpbmcgY29kZSwgdmVjdG9yPHBhaXI8Y2hhcixzdHJpbmc+PiYgY29kZXMpIHsKICAgIGlmICghcm9vdCkgcmV0dXJuOwoKICAgIGlmICghcm9vdC0+bGVmdCAmJiAhcm9vdC0+cmlnaHQpCiAgICAgICAgY29kZXMucHVzaF9iYWNrKHtyb290LT5jaCwgY29kZX0pOwoKICAgIGJ1aWxkQ29kZXMocm9vdC0+bGVmdCwgY29kZSArICIwIiwgY29kZXMpOwogICAgYnVpbGRDb2Rlcyhyb290LT5yaWdodCwgY29kZSArICIxIiwgY29kZXMpOwp9CgpzdHJpbmcgZW5jb2RlKHN0cmluZyB0ZXh0LCB2ZWN0b3I8cGFpcjxjaGFyLHN0cmluZz4+JiBjb2RlcykgewogICAgc3RyaW5nIHJlczsKCiAgICBmb3IgKGNoYXIgYyA6IHRleHQpCiAgICAgICAgZm9yIChhdXRvICZwIDogY29kZXMpCiAgICAgICAgICAgIGlmIChwLmZpcnN0ID09IGMpCiAgICAgICAgICAgICAgICByZXMgKz0gcC5zZWNvbmQ7CgogICAgcmV0dXJuIHJlczsKfQoKc3RyaW5nIGRlY29kZShzdHJpbmcgcywgTm9kZSogcm9vdCkgewogICAgc3RyaW5nIHJlczsKICAgIE5vZGUqIGN1ciA9IHJvb3Q7CgogICAgZm9yIChjaGFyIGIgOiBzKSB7CiAgICAgICAgY3VyID0gKGIgPT0gJzAnKSA/IGN1ci0+bGVmdCA6IGN1ci0+cmlnaHQ7CgogICAgICAgIGlmICghY3VyLT5sZWZ0ICYmICFjdXItPnJpZ2h0KSB7CiAgICAgICAgICAgIHJlcyArPSBjdXItPmNoOwogICAgICAgICAgICBjdXIgPSByb290OwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiByZXM7Cn0KCnZvaWQgcHJpbnRET1QoTm9kZSogcm9vdCkgewogICAgaWYgKCFyb290KSByZXR1cm47CgogICAgaWYgKHJvb3QtPmxlZnQpIHsKICAgICAgICBjb3V0IDw8ICJcIiIgPDwgcm9vdC0+Y2ggPDwgcm9vdC0+ZnJlcSA8PCAiXCIgLS0gXCIiCiAgICAgICAgICAgICA8PCByb290LT5sZWZ0LT5jaCA8PCByb290LT5sZWZ0LT5mcmVxIDw8ICJcIlxuIjsKICAgICAgICBwcmludERPVChyb290LT5sZWZ0KTsKICAgIH0KCiAgICBpZiAocm9vdC0+cmlnaHQpIHsKICAgICAgICBjb3V0IDw8ICJcIiIgPDwgcm9vdC0+Y2ggPDwgcm9vdC0+ZnJlcSA8PCAiXCIgLS0gXCIiCiAgICAgICAgICAgICA8PCByb290LT5yaWdodC0+Y2ggPDwgcm9vdC0+cmlnaHQtPmZyZXEgPDwgIlwiXG4iOwogICAgICAgIHByaW50RE9UKHJvb3QtPnJpZ2h0KTsKICAgIH0KfQoKaW50IG1haW4oKSB7CgogICAgc3RyaW5nIHRleHQgPSAiY2hlcHJhem92aXZhbiI7CgogICAgdmVjdG9yPE5vZGUqPiBub2RlczsKCiAgICBmb3IgKGNoYXIgYyA6IHRleHQpIHsKICAgICAgICBib29sIGZvdW5kID0gZmFsc2U7CgogICAgICAgIGZvciAoYXV0byAmbiA6IG5vZGVzKSB7CiAgICAgICAgICAgIGlmIChuLT5jaCA9PSBjKSB7CiAgICAgICAgICAgICAgICBuLT5mcmVxKys7CiAgICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKCFmb3VuZCkKICAgICAgICAgICAgbm9kZXMucHVzaF9iYWNrKG5ldyBOb2RlKGMsIDEpKTsKICAgIH0KCiAgICBwcmlvcml0eV9xdWV1ZTxOb2RlKiwgdmVjdG9yPE5vZGUqPiwgQ29tcGFyZT4gcHE7CgogICAgZm9yIChhdXRvIG4gOiBub2RlcykKICAgICAgICBwcS5wdXNoKG4pOwoKICAgIHdoaWxlIChwcS5zaXplKCkgPiAxKSB7CiAgICAgICAgTm9kZSogYSA9IHBxLnRvcCgpOyBwcS5wb3AoKTsKICAgICAgICBOb2RlKiBiID0gcHEudG9wKCk7IHBxLnBvcCgpOwoKICAgICAgICBwcS5wdXNoKG5ldyBOb2RlKCdcMCcsIGEtPmZyZXEgKyBiLT5mcmVxLCBhLCBiKSk7CiAgICB9CgogICAgTm9kZSogcm9vdCA9IHBxLnRvcCgpOwoKICAgIHZlY3RvcjxwYWlyPGNoYXIsc3RyaW5nPj4gY29kZXM7CiAgICBidWlsZENvZGVzKHJvb3QsICIiLCBjb2Rlcyk7CgogICAgY291dCA8PCAi0JrQvtC00Lgg0KXQsNGE0YTQvNCw0L3QsDpcbiI7CiAgICBmb3IgKGF1dG8gJnAgOiBjb2RlcykKICAgICAgICBjb3V0IDw8IHAuZmlyc3QgPDwgIiA6ICIgPDwgcC5zZWNvbmQgPDwgZW5kbDsKCiAgICBzdHJpbmcgZW5jID0gZW5jb2RlKHRleHQsIGNvZGVzKTsKICAgIGNvdXQgPDwgIlxuRU5DT0RFRDpcbiIgPDwgZW5jIDw8IGVuZGw7CgogICAgY291dCA8PCAiXG5ERUNPREVEOlxuIiA8PCBkZWNvZGUoZW5jLCByb290KSA8PCBlbmRsOwoKICAgIGNvdXQgPDwgIlxuRE9UOlxuZ3JhcGggRyB7XG4iOwogICAgcHJpbnRET1Qocm9vdCk7CiAgICBjb3V0IDw8ICJ9XG4iOwoKICAgIHJldHVybiAwOwp9