There is a Huffman method, but when executed in coding, line breaks are added somewhere and because of this an incorrect encoding occurs.
#include <iostream> #include <vector> #include <map> #include <list> #include <fstream> using namespace std; class Node { public: int number; //число char symbol; //символ Node *left, *right; Node() { left=right=NULL; } Node(Node *L, Node *R) { left = L; right = R; number = L->number + R->number; } }; //перегрузка параметров l, r struct MyCompare { bool operator()(const Node* l, const Node* r) const { // возвращаем True, если параметр l < r return l->number < r->number; } }; 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->left==NULL && root->right==NULL) table[root->symbol]=code; //ассоциируем эту букву с кодом code.pop_back(); } int main (int argc, char *argv[]) { setlocale(LC_ALL,"Russian"); if(argc != 4) { cout << "\n -----------------------------------------------" << endl; cout << " | Лабораторная работа №2 |" << endl; cout << " | Сжатие данных: метод Хаффмана |" << endl; cout << " -----------------------------------------------" << endl; cout << " ---------------------------------------------------------------" << endl; cout << "| Инструкция: |" << endl; cout << "| |" << endl; cout << "|\t [lab2] + |" << endl; cout << "| |" << endl; cout << "|\t [входной_файл.расширение] + |" << endl; cout << "|\t [кодируемый_файл.расширение] + |" << endl; cout << "|\t [декодируемый_файл.расширение] |" << endl; cout << "| |" << endl; cout << " ---------------------------------------------------------------" << endl; } else { // считаем частоты символов ifstream ifile(argv[1], ios::out | ios::binary); map<char,int> m; while (1) { int c = ifile.get(); if (c == -1) break; m[(char)c]++; } //while (!f.eof()) //{ char c = f.get(); // m[c]++;} // записываем начальные узлы в список list list<Node*> t; for( map<char,int>::iterator itr=m.begin(); itr!=m.end(); ++itr) { Node *p = new Node; p->symbol = itr->first; p->number = itr->second; t.push_back(p); } // создаем дерево while (t.size()!=1) { t.sort(MyCompare()); //сортируем list 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(); //root - указатель на вершину дерева // создаем пары 'символ-код': BuildTable(root); ifile.clear(); ifile.seekg(0); // перемещаем указатель снова в начало файла ofstream ofile(argv[2], ios::out | ios::binary); int count=0; char buf=0; while (!ifile.eof()) { char c = ifile.get(); vector<bool> x = table[c]; for(int n=0; n < x.size(); n++) { buf = buf | x[n]<<(7-count); count++; if (count==8) { count=0; ofile << buf; buf=0; } } } ifile.close(); ofile.close(); cout << "Сжатие выполнено..." << endl; ifstream iifile(argv[2], ios::in | ios::binary); ofstream oofile(argv[3]); Node *p = root; count = 0; char byte; byte = iifile.get(); while(!iifile.eof()) { bool b = byte & (1 << (7-count) ) ; if (b) p=p->right; else p=p->left; if (p->left==NULL && p->right==NULL) { oofile << p->symbol; p = root; } count++; if (count == 8) { count = 0; byte = iifile.get(); } } iifile.close(); oofile.close(); cout << "Файл разархивировано..." << endl; } return 0; } The text of the file to be encoded: qwqwqwqwqwqwqqqqqqqqqq \ n \ n \ n \ n \ n \ n \ n \ n \ ends with line breaks. Decodes the line in the text correctly until it adds more than 2 times hyphenation. Well, of course, this is all displayed on the dimensions: 1.txt - the encoded file 2.huf - encoded 3.txt - decoded 
I would be very grateful, there is someone who can help solve the problem.