Advertisement
Guest User

Untitled

a guest
May 23rd, 2018
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 21.21 KB | None | 0 0
  1. // Алгоритм сжатия данных Хаффмана
  2.  
  3. // Заголовки для тестирования вручную
  4. #include <iostream>
  5. #include <fstream>
  6.  
  7. // <vector>, <map>, <queue> для хранения промежуточных данных
  8. // <algorithm> для использования std::sort
  9. #include <algorithm>
  10. #include <vector>
  11. #include <map>
  12. #include <queue>
  13.  
  14.  
  15. // static void copyStream(IInputStream& input, IOutputStream& output)
  16. // {
  17. // byte value;
  18. // while (input.Read(value))
  19. // {
  20. // output.Write(value);
  21. // }
  22. // }
  23.  
  24.  
  25. // Тип хранимого элемента
  26. typedef char byte;
  27.  
  28. // Получение бита из байта под номером от 1 до 8 (нумерация слева направо)
  29. bool getBit(unsigned char number, char position)
  30. {
  31. switch (position)
  32. {
  33. case 1:
  34. return ((number & 128) != 0);
  35. case 2:
  36. return ((number & 64) != 0);
  37. case 3:
  38. return ((number & 32) != 0);
  39. case 4:
  40. return ((number & 16) != 0);
  41. case 5:
  42. return ((number & 8) != 0);
  43. case 6:
  44. return ((number & 4) != 0);
  45. case 7:
  46. return ((number & 2) != 0);
  47. case 8:
  48. return ((number & 1) != 0);
  49. default:
  50. return 1;
  51. }
  52. }
  53.  
  54. // Получение байта из 8 бит (n1 - старший разряд, n8 - младший)
  55. unsigned char getByte(bool n1, bool n2, bool n3, bool n4, bool n5, bool n6, bool n7, bool n8)
  56. {
  57. return n1 * 128 + n2 * 64 + n3 * 32 + n4 * 16 + n5 * 8 + n6 * 4 + n7 * 2 + n8;
  58. }
  59.  
  60.  
  61.  
  62. /////////////////////
  63. //// ENCODE PART ////
  64. /////////////////////
  65.  
  66.  
  67.  
  68. // Простой счетчик чтобы удобно передавать и принимать в функцию и из неё
  69. struct counter
  70. {
  71. int count;
  72.  
  73. void inc() { count++; };
  74.  
  75. counter() : count(0) {};
  76. };
  77.  
  78. // Структура для хранения кода символа и длины кода
  79. struct encodedSymbol
  80. {
  81. // Будем хранить 0 и 1
  82. std::vector<bool> data;
  83. // Будем иметь их количество
  84. int length;
  85.  
  86. encodedSymbol() : length(0) {};
  87.  
  88. ~encodedSymbol()
  89. {
  90. data.clear();
  91. }
  92. };
  93.  
  94. // Объект для хранения пары символ + частота
  95. struct symbolObject
  96. {
  97. // Частота с которой он встрчается
  98. int itsPercentage;
  99.  
  100. // Массив символов которые он содержит и их количество
  101. std::vector<unsigned char> symbols;
  102. int ElemenetsContaining = 0;
  103.  
  104. // 0 - левые повороты, 1 - правые повороты.
  105. // В code хранится 2 поля
  106. // data - массив из 0 и 1, слева направо получаем повороты от вершины
  107. // length - количество таких поворотов
  108. encodedSymbol code;
  109.  
  110. symbolObject* LeftChild;
  111. symbolObject* RightChild;
  112.  
  113. ~symbolObject()
  114. {
  115. delete LeftChild;
  116. delete RightChild;
  117. symbols.clear();
  118. }
  119.  
  120. symbolObject(int itsPercentage_, int ElementsContaining_, unsigned char symbol_) :
  121. itsPercentage(itsPercentage_),
  122. LeftChild(nullptr),
  123. RightChild(nullptr),
  124. ElemenetsContaining(ElementsContaining_)
  125. {
  126. symbols.push_back(symbol_);
  127. };
  128.  
  129. symbolObject() :
  130. itsPercentage(0),
  131. ElemenetsContaining(0),
  132. LeftChild(nullptr),
  133. RightChild(nullptr)
  134. {};
  135.  
  136. symbolObject(int itsPercentage_, int ElementsContaining_, std::vector<unsigned char>& first, std::vector<unsigned char>& second) :
  137. itsPercentage(itsPercentage_),
  138. LeftChild(nullptr),
  139. RightChild(nullptr),
  140. ElemenetsContaining(ElementsContaining_)
  141. {
  142. for (int i = 0; i < first.size(); i++)
  143. {
  144. symbols.push_back(first[i]);
  145. }
  146. for (int i = 0; i < second.size(); i++)
  147. {
  148. symbols.push_back(second[i]);
  149. }
  150. };
  151.  
  152.  
  153. };
  154.  
  155. // Рекурсивный обход дерева для создания кода элемента (рекурсивный вызов). Левый поворот: 0, правый поворот: 1
  156. void preOrder(symbolObject* root, counter *haffmanTreeAmountOfNodes)
  157. {
  158. if (root)
  159. {
  160. haffmanTreeAmountOfNodes->inc();
  161. // Если дошли до листа то выходим из функции, продолжать обход нам не надо
  162. if (root->LeftChild == nullptr && root->RightChild == nullptr)
  163. return;
  164.  
  165. // Если есть левый ребенок то вызываем рекурсивно обход левого поддерева
  166. // В код левого ребенка добавляем 0, длину левого кода ставим длину кода в данном узле + 1
  167. if (root->LeftChild != nullptr)
  168. {
  169. for (int i = 0; i < root->code.length; i++)
  170. {
  171. root->LeftChild->code.data.push_back(root->code.data[i]);
  172. }
  173.  
  174. root->LeftChild->code.data.push_back(0);
  175. root->LeftChild->code.length = root->code.length + 1;
  176. preOrder(root->LeftChild, haffmanTreeAmountOfNodes);
  177. }
  178.  
  179. // Если есть правый ребенок то вызываем рекурсивно обход правого поддерева
  180. // В код правого ребенка добавляем 1, длину правого кода ставим длину кода в данном узле + 1
  181. if (root->RightChild != nullptr)
  182. {
  183. for (int i = 0; i < root->code.length; i++)
  184. {
  185. root->RightChild->code.data.push_back(root->code.data[i]);
  186. }
  187.  
  188. root->RightChild->code.data.push_back(1);
  189. root->RightChild->code.length = root->code.length + 1;
  190. preOrder(root->RightChild, haffmanTreeAmountOfNodes);
  191. }
  192. }
  193. }
  194.  
  195. // Рекурсивный обход дерева для создания кода элемента (первичный вызов). Левый поворот: 0, правый поворот: 1
  196. void PreOrder(symbolObject* root, counter *haffmanTreeAmountOfNodes)
  197. {
  198. if (root)
  199. {
  200. haffmanTreeAmountOfNodes->inc();
  201.  
  202. // Рассмотрели случай если дерево состоит из 1 вершины
  203. // Т.е. один символ, кодируем его 0 и длина кода составит 1
  204. if (root->LeftChild == nullptr && root->RightChild == nullptr)
  205. {
  206. root->code.data.push_back(0);
  207. root->code.length = 1;
  208. return;
  209. }
  210.  
  211. // Иначе же, если есть хотя-бы один ребенок то длина кода корня 1
  212. root->code.length = 0;
  213.  
  214. // Если есть левый ребенок то вызываем рекурсивно обход левого поддерева
  215. // В код левого ребенка добавляем 0, длину левого кода ставим 1
  216. if (root->LeftChild != nullptr)
  217. {
  218. root->LeftChild->code.data.push_back(0);
  219. root->LeftChild->code.length = 1;
  220. preOrder(root->LeftChild, haffmanTreeAmountOfNodes);
  221. }
  222.  
  223. // Если есть правый ребенок то вызываем рекурсивно обход правого поддерева
  224. // В код правого ребенка добавляем 1, длину правого кода ставим 1
  225. if (root->RightChild != nullptr)
  226. {
  227. root->RightChild->code.data.push_back(1);
  228. root->RightChild->code.length = 1;
  229. preOrder(root->RightChild, haffmanTreeAmountOfNodes);
  230. }
  231. }
  232. }
  233.  
  234. // Предикат отношения для сортировки вектора из symbolObject
  235. bool predikat(symbolObject* a, symbolObject* b)
  236. {
  237. return a->itsPercentage > b->itsPercentage;
  238. }
  239.  
  240. // InOrder обход чтобы зашифровать дерево
  241. void InOrderHaffmanTree(symbolObject* Root, std::vector<bool>& haffman)
  242. {
  243. if (Root->LeftChild != nullptr || Root->RightChild != nullptr)
  244. {
  245. haffman.push_back(1);
  246. }
  247. else
  248. {
  249. haffman.push_back(0);
  250.  
  251. for (int p = 1; p <= 8; p++)
  252. haffman.push_back(getBit(Root->symbols[0], p));
  253. }
  254.  
  255. if (Root->LeftChild)
  256. {
  257. InOrderHaffmanTree(Root->LeftChild, haffman);
  258. }
  259.  
  260. if (Root->RightChild)
  261. {
  262. InOrderHaffmanTree(Root->RightChild, haffman);
  263. }
  264. }
  265.  
  266. // Функция кодировки (Главная функция)
  267. void Encode(IInputStream& original, IOutputStream& compressed)
  268. {
  269. std::vector<unsigned char> string;
  270.  
  271. // Ассоциативный массив: индексы - символы, значение - частота символа
  272. std::map<unsigned char, std::vector<int>> indivSymbols;
  273.  
  274. // 2 идентичных массива с индивидуальными символами: значения - указатели на объекты symbolObject*
  275. // Обновляем массив percentage актуальными данными
  276. std::vector <symbolObject*> symbols;
  277. std::vector <symbolObject*> symbolsCOPY;
  278.  
  279. //std::ifstream fin;
  280. //fin.open("SOURCE.txt");
  281. //char abc;
  282. //while (fin >> abc)
  283. //{
  284. // string.push_back(abc);
  285.  
  286. // indivSymbols[abc].push_back(1);
  287.  
  288. //};
  289.  
  290. byte value;
  291. while (original.Read(value))
  292. {
  293. string.push_back(value);
  294.  
  295.  
  296. indivSymbols[value].push_back(1);
  297. }
  298.  
  299. for (std::map<unsigned char, std::vector<int>>::iterator it = indivSymbols.begin(); it != indivSymbols.end(); ++it)
  300. {
  301. symbolObject *temp = new symbolObject();
  302. temp->symbols.push_back(it->first);
  303. temp->itsPercentage = it->second.size();
  304.  
  305. symbols.push_back(temp);
  306. symbolsCOPY.push_back(temp);
  307.  
  308. }
  309.  
  310. int symbols_count = symbols.size();
  311.  
  312. int n = string.size();
  313. //fin.close();
  314.  
  315. // Если ничего не ввели то завершились
  316. if (string.size() == 0)
  317. return;
  318.  
  319. // Предикат сравнения для создания очереди из символов
  320. struct customLess {
  321. bool operator()(symbolObject *a, symbolObject *b)
  322. {
  323. return a->itsPercentage > b->itsPercentage;
  324. }
  325. };
  326.  
  327. // Создание очереди из символов
  328. std::priority_queue<symbolObject*, std::vector<symbolObject*>, customLess> queue;
  329. for (int i = 0; i < symbols_count; i++)
  330. {
  331. queue.push(symbols[i]);
  332. }
  333.  
  334. // Создание дерева Хаффмана
  335. for (int i = 1; i < symbols_count; i++)
  336. {
  337. symbolObject *temp = new symbolObject();
  338.  
  339. temp->LeftChild = queue.top();
  340. queue.pop();
  341. temp->RightChild = queue.top();
  342. queue.pop();
  343.  
  344. temp->itsPercentage = temp->LeftChild->itsPercentage + temp->RightChild->itsPercentage;
  345.  
  346. queue.push(temp);
  347. }
  348.  
  349. // Получили корень дерева Хаффмана
  350. symbolObject *HaffmanTreeRoot;
  351. HaffmanTreeRoot = queue.top();
  352. queue.pop();
  353.  
  354. // Считаем путь до каждого символа рекурсивно изнутри этой функции, путь пишется внутри объекта SymbolObject
  355. counter *haffmanTreeAmountOfNodes = new counter;
  356. PreOrder(HaffmanTreeRoot, haffmanTreeAmountOfNodes);
  357.  
  358. // Строим таблицу хаффмана
  359. std::map<unsigned char, symbolObject*> table;
  360. for (int i = 0; i < symbols_count; i++)
  361. {
  362. table[symbolsCOPY[i]->symbols[0]] = symbolsCOPY[i];
  363. }
  364.  
  365. // Сохраняем дерево в побитовый массив haffman
  366. std::vector<bool> haffman;
  367. InOrderHaffmanTree(HaffmanTreeRoot, haffman);
  368.  
  369. // Сохранили бит шифрования, хаффмана и зашифрованную строку в битовый массив
  370. std::vector<bool> output_coded;
  371. output_coded.push_back(0);
  372. for (int f = 0; f < haffman.size(); f++)
  373. output_coded.push_back(haffman[f]);
  374.  
  375. /////////////////////////////////////////////////////////////////////////////////////////////////////
  376. int codedmessageSize = 0;
  377. for (int i = 0; i < n; i++)
  378. {
  379. for (int p = 0; p < table[string[i]]->code.length; p++)
  380. {
  381. output_coded.push_back(table[string[i]]->code.data[p]);
  382. codedmessageSize++;
  383. }
  384. }
  385. /////////////////////////////////////////////////////////////////////////////////////////////////////
  386.  
  387. int countofEightMinusBitsinlastbyte = (8 - output_coded.size() % 8) % 8;
  388. for (int f = 0; f < countofEightMinusBitsinlastbyte; f++)
  389. output_coded.push_back(0);
  390. for (int f = 1; f <= 8; f++)
  391. output_coded.push_back(getBit((8 - countofEightMinusBitsinlastbyte) % 8, f));
  392.  
  393. bool e;
  394.  
  395. /* Если зашифрованное весит больше чем сама строка то 0 */
  396. /* Если зашифрованное весит меньше чем сама строка то 1 */
  397. (output_coded.size()) >= ((string.size() * 8) + 8) ? e = false : e = true;
  398.  
  399. // Делаем битовый выходной массив
  400. if (e) // Если выводим зашифрованное
  401. {
  402. output_coded[0] = e;
  403. }
  404. else { // Если выводим исходное
  405. output_coded.clear();
  406. output_coded.push_back(e);
  407. for (int f = 1; f <= 7; f++)
  408. output_coded.push_back(0);
  409. for (int f = 0; f < string.size(); f++)
  410. {
  411. for (int p = 1; p <= 8; p++)
  412. output_coded.push_back(getBit(string[f], p));
  413. }
  414. }
  415.  
  416. // Делаем байтовый выходной массив
  417. std::vector<unsigned char> output_byte;
  418. for (int f = 0; f < output_coded.size() / 8; f++)
  419. {
  420. output_byte.push_back(getByte(output_coded[f * 8 + 0], output_coded[f * 8 + 1], output_coded[f * 8 + 2], output_coded[f * 8 + 3], output_coded[f * 8 + 4], output_coded[f * 8 + 5], output_coded[f * 8 + 6], output_coded[f * 8 + 7]));
  421. }
  422.  
  423. //// ТЕСТОВЫЙ ВЫВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВЫВОД ИЗ ПОТОКА ВЫВОДА //
  424. std::ofstream fout;
  425. fout.open("ENCODED.txt");
  426. for (int f = 0; f < output_byte.size(); f++) { fout << output_byte[f]; };
  427. fout.close();
  428. //// ТЕСТОВЫЙ ВВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВВОД ИЗ ПОТОКА ВВОДА //
  429.  
  430. for (int f = 0; f < output_byte.size(); f++) { compressed.Write(output_byte[f]); };
  431.  
  432. string.clear();
  433. indivSymbols.clear();
  434. symbols.clear();
  435. symbolsCOPY.clear();
  436. table.clear();
  437. haffman.clear();
  438. output_coded.clear();
  439. output_byte.clear();
  440.  
  441. return;
  442. }
  443.  
  444.  
  445.  
  446. /////////////////////
  447. //// DECODE PART ////
  448. /////////////////////
  449.  
  450. struct string_BIT_struct
  451. {
  452. std::vector<bool> data;
  453. int lastindex;
  454.  
  455. ~string_BIT_struct()
  456. {
  457. data.clear();
  458. }
  459.  
  460. };
  461.  
  462. void buildhaffmantree(symbolObject* Root, string_BIT_struct* string_BIT)
  463. {
  464. string_BIT->lastindex++;
  465.  
  466. if (string_BIT->data[string_BIT->lastindex]) // Если 1 т.е. узел
  467. {
  468. Root->LeftChild = new symbolObject();
  469. buildhaffmantree(Root->LeftChild, string_BIT);
  470.  
  471. Root->RightChild = new symbolObject();
  472. buildhaffmantree(Root->RightChild, string_BIT);
  473. }
  474. else // Если 0 т.е. лист
  475. {
  476. Root->LeftChild = nullptr;
  477. Root->RightChild = nullptr;
  478.  
  479. unsigned char temp = 0;
  480. temp = getByte(string_BIT->data[string_BIT->lastindex + 1], string_BIT->data[string_BIT->lastindex + 2], string_BIT->data[string_BIT->lastindex + 3], string_BIT->data[string_BIT->lastindex + 4], string_BIT->data[string_BIT->lastindex + 5], string_BIT->data[string_BIT->lastindex + 6], string_BIT->data[string_BIT->lastindex + 7], string_BIT->data[string_BIT->lastindex + 8]);
  481. string_BIT->lastindex = string_BIT->lastindex + 8;
  482. Root->symbols.push_back(temp);
  483. }
  484. }
  485.  
  486. void BuildHaffManTree(symbolObject* Root, string_BIT_struct* string_BIT)
  487. {
  488.  
  489. string_BIT->lastindex = 1;
  490.  
  491. Root->LeftChild = new symbolObject();
  492. buildhaffmantree(Root->LeftChild, string_BIT);
  493.  
  494. Root->RightChild = new symbolObject();
  495. buildhaffmantree(Root->RightChild, string_BIT);
  496.  
  497. }
  498.  
  499.  
  500.  
  501. void Decode(IInputStream& compressed, IOutputStream& original)
  502. {
  503. std::vector<unsigned char> OUTPUT;
  504. std::vector<unsigned char> string_BYTE;
  505. // ТЕСТОВЫЙ ВВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВВОД ИЗ ПОТОКА ВВОДА //
  506. std::ifstream fin;
  507. fin.open("ENCODED.txt");
  508. char abc;
  509. while (fin >> abc) { string_BYTE.push_back(abc); };
  510. int n = string_BYTE.size();
  511. fin.close();
  512. // ТЕСТОВЫЙ ВВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВВОД ИЗ ПОТОКА ВВОДА //
  513.  
  514. /* byte value;
  515. while (compressed.Read(value))
  516. {
  517. string_BYTE.push_back(value);
  518. }*/
  519.  
  520. // Если ничего не ввели
  521. if (string_BYTE.size() == 0)
  522. return;
  523.  
  524. // Вектор хранящий закодированный файл в битовом формате
  525. string_BIT_struct string_BIT;
  526. for (int i = 0; i < string_BYTE.size(); i++)
  527. {
  528. for (int p = 1; p <= 8; p++)
  529. string_BIT.data.push_back(getBit(string_BYTE[i], p));
  530. }
  531.  
  532. if (string_BIT.data[0] == 0) // Если строка пришла в исходном формате
  533. {
  534. // Просто вывести ее
  535. int amountofbytesinencodedstring = string_BYTE.size();
  536. // Нужно начать выводить байты с 9-го бита
  537.  
  538. for (int i = 1; i < amountofbytesinencodedstring; i++)
  539. {
  540. byte temp = getByte(string_BIT.data[i * 8], string_BIT.data[i * 8+1], string_BIT.data[i * 8+2], string_BIT.data[i * 8+3], string_BIT.data[i * 8+4], string_BIT.data[i * 8+5], string_BIT.data[i * 8+6], string_BIT.data[i * 8+7]);
  541. OUTPUT.push_back(temp);
  542. }
  543.  
  544. //// ТЕСТОВЫЙ ВЫВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВЫВОД ИЗ ПОТОКА ВЫВОДА //
  545. std::ofstream fout;
  546. fout.open("DECODED.txt");
  547. for (int f = 0; f < OUTPUT.size(); f++) { fout << OUTPUT[f]; };
  548. fout.close();
  549. //// ТЕСТОВЫЙ ВВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВВОД ИЗ ПОТОКА ВВОДА //
  550.  
  551.  
  552. for (int f = 0; f < OUTPUT.size(); f++) { original.Write(OUTPUT[f]); };
  553.  
  554. OUTPUT.clear();
  555. string_BYTE.clear();
  556.  
  557.  
  558. return;
  559. }
  560. else
  561. {
  562.  
  563. symbolObject *HaffmanTreeRoot = new symbolObject();
  564. if (string_BIT.data[1] == 1) // Т.е. в начале дерева Хаффмана узел => имеет минимум 2 ребенка
  565. {
  566. BuildHaffManTree(HaffmanTreeRoot, &string_BIT);
  567. // lastindex ссылается на ячейку в которой начинается код зашифрованной строки
  568. string_BIT.lastindex++;
  569. }
  570. else // Т.е. в начале дерева Хаффмана лист => состоит из одного узла
  571. {
  572. unsigned char temp = getByte(string_BIT.data[2], string_BIT.data[3], string_BIT.data[4], string_BIT.data[5], string_BIT.data[6], string_BIT.data[7], string_BIT.data[8], string_BIT.data[9]);
  573. HaffmanTreeRoot->symbols.push_back(temp);
  574. // lastindex ссылается на ячейку в которой начинается код зашифрованной строки
  575. string_BIT.lastindex = 10;
  576.  
  577.  
  578. }
  579.  
  580. int countOfBitsInPreLastByte = 0;
  581. int abk = string_BIT.data.size() - 1;
  582. countOfBitsInPreLastByte = string_BIT.data[abk - 3] * 8 + string_BIT.data[abk - 2] * 4 + string_BIT.data[abk - 1] * 2 + string_BIT.data[abk];
  583.  
  584. int indexOfLastBitCodingString;
  585. if (countOfBitsInPreLastByte == 0)
  586. indexOfLastBitCodingString = string_BIT.data.size() - 8 - 1;
  587. else
  588. indexOfLastBitCodingString = string_BIT.data.size() - 8 - 8 + countOfBitsInPreLastByte - 1;
  589.  
  590. //////////////////////////////////////
  591.  
  592. std::vector<bool> codedstringONLYCODEDSYMBOLS;
  593.  
  594. // Считаем количество значащих бит в предпоследнем байте
  595. int amountofbitsintheprelastbyte = countOfBitsInPreLastByte;
  596.  
  597. // lastindex - храним индекс ячейки в которой лежит последний бит зашифрованных символов
  598. int lastindex = indexOfLastBitCodingString;
  599.  
  600. // В массиве codedstringONLYCODEDSYMBOLS лежат закодированные символы
  601. for (int p = string_BIT.lastindex; p <= lastindex; p++)
  602. {
  603. codedstringONLYCODEDSYMBOLS.push_back(string_BIT.data[p]);
  604. }
  605.  
  606.  
  607. // Осталось расшифровать строку при помощи дерева
  608. symbolObject *Node;
  609. Node = HaffmanTreeRoot;
  610.  
  611. if (string_BIT.data[1] == 1) // Т.е. минимум 2 символа
  612. {
  613. for (int p = 0; p < codedstringONLYCODEDSYMBOLS.size(); p++) {
  614.  
  615. if (codedstringONLYCODEDSYMBOLS[p] == 0)
  616. Node = Node->LeftChild;
  617. if (codedstringONLYCODEDSYMBOLS[p] == 1)
  618. Node = Node->RightChild;
  619.  
  620. if ((Node->LeftChild == nullptr) &( Node->RightChild == nullptr))
  621. {
  622. OUTPUT.push_back(Node->symbols[0]);
  623. Node = HaffmanTreeRoot;
  624. }
  625. }
  626. }
  627. else
  628. {
  629. for (int p = 0; p < codedstringONLYCODEDSYMBOLS.size(); p++)
  630. {
  631. OUTPUT.push_back(HaffmanTreeRoot->symbols[0]);
  632. }
  633.  
  634. int abbsdbfasd = 0;
  635. }
  636.  
  637.  
  638. for (int f = 0; f < OUTPUT.size(); f++) { original.Write(OUTPUT[f]); };
  639.  
  640. codedstringONLYCODEDSYMBOLS.clear();
  641.  
  642.  
  643. }
  644.  
  645.  
  646. //// ТЕСТОВЫЙ ВЫВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВЫВОД ИЗ ПОТОКА ВЫВОДА //
  647. std::ofstream fout;
  648. fout.open("DECODED.txt");
  649. for (int f = 0; f < OUTPUT.size(); f++) { fout << OUTPUT[f]; };
  650. fout.close();
  651. //// ТЕСТОВЫЙ ВВОД ДЛЯ ТЕСТИРОВАНИЯ | В ПОСЛЕДСТВИИ ЗАМЕНИТЬ НА ВВОД ИЗ ПОТОКА ВВОДА //
  652.  
  653. OUTPUT.clear();
  654. string_BYTE.clear();
  655.  
  656. return;
  657. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement