Как восстановить дерево Хаффмана
Есть готовый алгоритм Хаффмана на C++. В моём случае я храню символы и их частоты в файле, по ним нужно восстановить дерево. Возможно ли это или нужно иначе сохранять дерево?
#include <stdio.h>
#include <vector>
#include <map>
#include <iostream>
#include <fstream>
#include <list>
#include <conio.h>
#include <windows.h>
#include <sstream>
#include <locale>
#include <io.h>
#include <fcntl.h>
#include <string>
#include <codecvt>
using namespace std;
class Node
{
public:
int a;
wchar_t c;
Node* left, * right;
Node()
{
left = right = NULL;
}
Node(Node* L, Node* R)
{
left = L;
right = R;
a = L->a + R->a;
}
};
struct MyCompare
{
bool operator()(const Node* l, const Node* r) const { return l->a < r->a; }
};
vector<bool> code;
map<char, vector<bool> > table;
void BuildTable(Node* root)
{
if (root->left != NULL)
{
code.push_back(0);
BuildTable(root->left);
}
if (root->right != NULL)
{
code.push_back(1);
BuildTable(root->right);
}
if (root->c)
table[root->c] = code;
if (code.size() != 0)
{
code.pop_back();
}
}
int main(int argc, char* argv[])
{
setlocale(LC_ALL, "Russian");
int check;
cout << "Желаете закодировать Ваш файл?\n 1 - Да.\n 2 - Нет." << endl;
cin >> check;
if (check == 1)
{
wifstream f("C:\\Users\\artem\\Downloads\\test.txt");
f.imbue(std::locale(".utf-8"));
map<wchar_t, int> m;
while (!f.eof())
{
wchar_t c = f.get();
m[c]++;
}
std::wofstream file_with_table("file_with_table.txt");
file_with_table.imbue(std::locale(".utf-8"));
map<wchar_t, int>::iterator i;
for (i = m.begin(); i != m.end(); ++i)
{
wchar_t sym = i->first;
file_with_table << sym << " " << i->second << endl;
}
file_with_table.close();
list<Node*> t;
for (map<wchar_t, int>::iterator itr = m.begin(); itr != m.end(); ++itr)
{
Node* p = new Node;
p->c = itr->first;
p->a = itr->second;
t.push_back(p);
}
while (t.size() != 1)
{
t.sort(MyCompare());
Node* SonL = t.front();
t.pop_front();
Node* SonR = t.front();
t.pop_front();
Node* parent = new Node(SonL, SonR);
t.push_back(parent);
}
Node* root = t.front();
BuildTable(root);
f.clear(); f.seekg(0);
ofstream g("output.bin");
int count = 0;
char buf = 0;
int show_coded_text;
int start_time;
cout << "\nЖелаете увидеть закодированный текст?\n 1 - Да.\n 2 - Нет.\n ";
cin >> show_coded_text;
start_time = clock();
int n;
while (!f.eof())
{
char c = f.get();
vector<bool> x = table[c];
for (n = 0; n < x.size(); n++)
{
buf = buf | x[n] << (7 - count);
count++;
if (count == 8)
{
count = 0;
g << buf;
buf = 0;
}
if (show_coded_text == 1)
{
cout << x[n];
}
}
}
f.close();
g.close();
int end_time = clock();
int search_time = end_time - start_time;
cout << "\n\nЗатраченное время: " << search_time / 1000.0 << "\n";
int number;
cout << endl << endl << " Желаете декодировать Ваш файл?\n 1 - Да.\n 2 - Нет." << endl;
cin >> number;
int start_decoding_time;
cout << endl;
if (number == 1)
{
ifstream F("output.bin");
wofstream D("Decoded text.txt");
D.imbue(std::locale(".utf-8"));
Node* p = root;
count = 0;
char byte;
byte = F.get();
int show_decoded_text;
cout << " Желаете увидеть декодированный файл?\n 1 - Да.\n 2 - Нет.\n";
cin >> show_decoded_text;
start_decoding_time = clock();
while (!F.eof())
{
bool b = byte & (1 << (7 - count));
if (b)
p = p->right;
else p = p->left;
if ((p->left == NULL) && (p->right == NULL))
{
if (show_decoded_text == 1)
{
cout << p->c;
}
D << p->c;
p = root;
}
count++;
if (count == 8)
{
count = 0;
byte = F.get();
}
}
F.close();
int stop_decoding_time = clock();
int search_decoding_time = stop_decoding_time - start_decoding_time;
cout << "\nФайл декодирован.";
cout << "\nЗатраченное время: " << search_decoding_time / 1000.0 << "\n";
}
_getch();
return 0;
}
}