Advertisement
meta1211

Untitled

Feb 9th, 2019
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.96 KB | None | 0 0
  1. #include <string>
  2. #include <vector>
  3. #include <fstream>
  4. #include <map>
  5. #include <list>
  6. #include <iostream>
  7. #include <bitset>
  8. #include "BinaryTree.h"
  9. #include <cmath>
  10. #pragma region Legacy
  11.  
  12. std::string ReadAllAsString(std::string path)
  13. {
  14.     std::ifstream ifs(path);
  15.     std::string s;
  16.     std::getline(ifs, s, (char)ifs.eof());
  17.     ifs.close();
  18.     return s;
  19. }
  20.  
  21. std::vector<std::string> ReadAllStrings(std::string path)
  22. {
  23.     std::fstream reader(path);
  24.     std::vector<std::string> allStrings;
  25.     if (reader.is_open())
  26.     {
  27.         std::string nextString;
  28.         while (!reader.eof())
  29.         {
  30.             std::getline(reader, nextString);
  31.             allStrings.push_back(nextString);
  32.             nextString.clear();
  33.         }
  34.     }
  35.     else
  36.     {
  37.         allStrings.push_back("WRONG FILE PATH: " + path);
  38.         std::cout << "Wrong path!";
  39.     }
  40.     return allStrings;
  41. }
  42.  
  43. std::vector<std::string> SplitString(const std::string &str, char separator)
  44. {
  45.     std::vector<std::string> words;
  46.     std::string word;
  47.     for (auto ch : str)
  48.     {
  49.         if (ch == separator)
  50.         {
  51.             words.push_back(word);
  52.             word.clear();
  53.         }
  54.         else
  55.         {
  56.             word.push_back(ch);
  57.         }
  58.     }
  59.     if (word.length() > 0)
  60.     {
  61.         words.push_back(word);
  62.     }
  63.     return words;
  64. }
  65.  
  66. void WriteAllStrings(std::string path, std::vector<std::string> text)
  67. {
  68.     std::ofstream writer(path);
  69.     for (auto str : text)
  70.     {
  71.         writer << str;
  72.     }
  73.     writer.close();
  74. }
  75.  
  76. std::map<char, size_t> AnalyzeSymbolsFrequency(std::vector<std::string> text)
  77. {
  78.     std::map<char, size_t> result;
  79.     for (auto str : text)
  80.     {
  81.         for (char symbol : str)
  82.         {
  83.             result[symbol]++;
  84.         }
  85.     }
  86.     return result;
  87. }
  88.  
  89. std::map<char, size_t> AnalyzeSymbolsFrequency(std::string &text)
  90. {
  91.     std::map<char, size_t> result;
  92.     for (char &symbol : text)
  93.     {
  94.         result[symbol]++;
  95.     }
  96.     return result;
  97. }
  98.  
  99. void Print(std::list<BinaryTree> &trees)
  100. {
  101.     for (auto tree : trees)
  102.     {
  103.         std::cout << tree.GetRoot()->GetFrequency() << ' ';
  104.     }
  105.     std::cout << '\n';
  106. }
  107.  
  108. BinaryTree CreateHaffamnsTree(const std::map<char, size_t> &symbolsData)
  109. {
  110.     std::list<BinaryTree> HaffmanTrees;
  111.     for (auto pair : symbolsData)
  112.     {
  113.         HaffmanTrees.push_back(new Node(pair.first, pair.second));
  114.     }
  115.     while (HaffmanTrees.size() > 1)
  116.     {
  117.         HaffmanTrees.sort();
  118.         BinaryTree &first = *HaffmanTrees.begin();
  119.         BinaryTree &second = *std::next(HaffmanTrees.begin(), 1);
  120.         BinaryTree merged = first + second;
  121.         HaffmanTrees.pop_front();
  122.         HaffmanTrees.pop_front();
  123.         HaffmanTrees.push_back(merged);
  124.     }
  125.     return *(HaffmanTrees.begin()); //we always have only one tree in an array in the end.
  126. }
  127.  
  128. void ReadCode(Node *node, std::map<char, std::string> &codeTable, std::string curCode)
  129. {
  130.     if (node->GetLeft())
  131.     {
  132.         ReadCode(node->GetLeft(), codeTable, curCode + "0");
  133.         if (node->GetRight())
  134.         {
  135.             ReadCode(node->GetRight(), codeTable, curCode + "1");
  136.         }
  137.     }
  138.     else
  139.     {
  140.         codeTable.insert(std::pair<char, std::string>(node->GetSymbol(), curCode));
  141.     }
  142. }
  143.  
  144. std::map<char, std::string> CreateCodeFromTree(BinaryTree &codeTree)
  145. {
  146.     std::map<char, std::string> codeTable;
  147.     ReadCode(codeTree.GetRoot(), codeTable, "");
  148.     return codeTable;
  149. }
  150.  
  151. unsigned char ConvertStringToByte(std::string str)
  152. {
  153.     unsigned char byte = 0;
  154.     for (size_t i = 8 - str.size(); i < 8; i++)
  155.     {
  156.         if (str[7 - i] == '1')
  157.         {
  158.             byte = byte | (1 << i);
  159.         }
  160.     }
  161.     return byte;
  162. }
  163.  
  164. std::string ConvertByteToString(unsigned char byte)
  165. {
  166.     std::string str = "";
  167.     for (size_t i = 0; i < 8; i++)
  168.     {
  169.         str.push_back((((1 <<(7 - i)) & byte) ? '1' : '0'));
  170.     }
  171.     return str;
  172. }
  173.  
  174. std::map<std::string, char> CreateTable(std::string tableAsString)
  175. {
  176.     std::map<std::string, char> result;
  177.     std::string code = "";
  178.     for (size_t i = 0; i < tableAsString.length(); i++)
  179.     {
  180.         if (tableAsString[i] == ' ')
  181.         {
  182.             result.insert(std::make_pair(code, tableAsString[i + 1]));
  183.             code.clear();
  184.             i += 2;
  185.         }
  186.         else
  187.         {
  188.             code.push_back(tableAsString[i]);
  189.         }
  190.     }
  191.     return result;
  192. }
  193.  
  194.  
  195. void Compress(std::string text, std::map<char, std::string> codeTable, std::string output)
  196. {
  197.     std::ofstream writer(output);
  198.     std::ofstream tableWriter(output + ".enc");
  199.     for (auto code : codeTable)
  200.     {
  201.         tableWriter << code.second << ' ' << code.first << '\n';
  202.     }
  203.     std::string byteAsString = "";
  204.     for (auto symbol : text)
  205.     {
  206.         std::string code = codeTable[symbol];
  207.         for (size_t i = 0; i < code.size(); i++)
  208.         {
  209.             byteAsString.push_back(code[i]);
  210.             if (byteAsString.size() == 8)
  211.             {
  212.                 writer << ConvertStringToByte(byteAsString);
  213.                 byteAsString.clear();
  214.             }
  215.         }
  216.     }
  217.     writer.close();
  218.     tableWriter.close();
  219. }
  220.  
  221.  
  222. std::string Decompress(std::string path)
  223. {
  224.     auto encodeTable = CreateTable(path + ".enc");
  225.     std::string text = "";
  226.     std::string curentCode = "";
  227.     std::ifstream reader(path);
  228.     unsigned char byte;
  229.     auto WTF = ReadAllAsString(path);
  230.     while(!reader.eof())
  231.     {
  232.         reader >> byte;
  233.         std::string bits = ConvertByteToString(byte);
  234.         for (size_t i = 0; i < 8; i++)
  235.         {
  236.             curentCode.push_back(bits[i]);
  237.             if (encodeTable.find(curentCode) != encodeTable.end())
  238.             {
  239.                 text.push_back(encodeTable[curentCode]);
  240.                 curentCode.clear();
  241.             }
  242.         }
  243.     }
  244.     return text;
  245. }
  246.  
  247. #pragma endregion
  248.  
  249. // write
  250. void Write(std::string path, std::bitset<8> byte)
  251. {
  252.     std::ofstream output(path, std::ios::binary);
  253.     unsigned long n = byte.to_ulong();
  254.     output.write(reinterpret_cast<const char*>(&n), sizeof(n));
  255. }
  256.  
  257. std::vector<unsigned char> TestCompress(std::string text, std::map<char, std::string> codeTable, std::string output)
  258. {
  259.     std::ofstream writer(output, std::ios::binary);
  260.     std::string byteAsString = "";
  261.     std::vector<unsigned char> text1;
  262.     for (auto symbol : text)
  263.     {
  264.         std::string code = codeTable[symbol];
  265.         for (size_t i = 0; i < code.size(); i++)
  266.         {
  267.             byteAsString.push_back(code[i]);
  268.             if (byteAsString.size() == 8)
  269.             {
  270.                 unsigned char DAFAQ = ConvertStringToByte(byteAsString);
  271.                 text1.push_back(DAFAQ);
  272.                 writer.write(reinterpret_cast<const char*>(&DAFAQ), sizeof(DAFAQ));
  273.                 byteAsString.clear();
  274.             }
  275.         }
  276.     }
  277.     if (byteAsString.size() > 0)
  278.     {
  279.         unsigned char DAFAQ = ConvertStringToByte(byteAsString);
  280.         text1.push_back(DAFAQ);
  281.         writer.write(reinterpret_cast<const char*>(&DAFAQ), sizeof(DAFAQ));
  282.     }
  283.     std::ofstream tableWriter(output + ".enc");
  284.     tableWriter << (8 - byteAsString.size()) << '\n';
  285.     for (auto code : codeTable)
  286.     {
  287.         tableWriter << code.second << ' ' << code.first << '\n';
  288.     }
  289.  
  290.     return text1;
  291. }
  292.  
  293. std::vector<unsigned char> Read(std::string path)
  294. {
  295.     std::ifstream input(path, std::ios::binary);
  296.     std::vector<unsigned char> text;
  297.     unsigned char byte;
  298.     while (!input.eof())
  299.     {
  300.         input.read(reinterpret_cast<char*>(&byte), sizeof(byte));
  301.         text.push_back(byte);
  302.     }
  303.     std::cout << (int)text[text.size() - 3] << ' ' << (int)text[text.size() - 2] << ' ' << (int)text[text.size() - 1] << '\n';
  304.     return text;
  305. }
  306.  
  307. std::string TestDecompress(std::string path)
  308. {
  309.     auto table = ReadAllAsString(path + ".enc");
  310.     int zeroesCount = (table[0] - '0');
  311.     table = table.substr(2, table.size() - 1);
  312.     auto encodeTable = CreateTable(table);
  313.     std::string text = "";
  314.     std::string curentCode = "";
  315.     std::ifstream reader(path, std::ios::binary);
  316.     unsigned char byte;
  317.     auto WTF = Read(path);
  318.     for (size_t i = 0; i < WTF.size() - 1; i++)
  319.     {
  320.         for (auto digit : std::bitset<8>(WTF[i]).to_string())
  321.         {
  322.             curentCode.push_back(digit);
  323.             if (encodeTable.find(curentCode) != encodeTable.end())
  324.             {
  325.                 text.push_back(encodeTable[curentCode]);
  326.                 curentCode.clear();
  327.             }
  328.         }
  329.     }
  330.     //The last byte might not be used comletely.
  331.     std::string lastByte = std::bitset<8>(WTF[WTF.size() - 1]).to_string();
  332.     for (size_t i = 0; i < 8 - zeroesCount; i++)
  333.     {
  334.         curentCode.push_back(lastByte[i]);
  335.         if (encodeTable.find(curentCode) != encodeTable.end())
  336.         {
  337.             text.push_back(encodeTable[curentCode]);
  338.             curentCode.clear();
  339.         }
  340.     }
  341.     return text;
  342. }
  343.  
  344. int main()
  345. {
  346.     const std::string input = "input.txt";
  347.     const std::string output = "output.txt";
  348.     auto text = ReadAllAsString(input);
  349.     auto frequency = AnalyzeSymbolsFrequency(text);
  350.     BinaryTree codesTree = CreateHaffamnsTree(frequency);
  351.     auto codeTable = CreateCodeFromTree(codesTree);
  352.  
  353.     //Old byte compressor
  354.  
  355.     //Compress(text, codeTable, output);
  356.     //std::string decompText = Decompress(output);
  357.     //std::ofstream A("decoded.txt");
  358.     //A.write(decompText.c_str(), decompText.size());
  359.     //A.close();
  360.     //if (decompText == text)
  361.     //{
  362.     //  std::cout << "YAAAAAAAAAAY\n";
  363.     //}
  364.     //else
  365.     //{
  366.     //  std::cout << "TOTALY NOT YAAAAAAAAAAAAAAAY \n";
  367.     //}
  368.  
  369.     //Non byte compressor
  370.  
  371.     //std::ofstream writer("decoded.txt");
  372.     //NonByteCompress(text, codeTable, output);
  373.     //auto decompText = NonByteDecompress(output);
  374.     //writer.write(decompText.c_str(), decompText.size());
  375.  
  376.     std::ofstream writer("decoded.txt");
  377.     auto f = TestCompress(text, codeTable, output);
  378.     auto sec = Read(output);
  379.     auto decompText = TestDecompress(output);
  380.     for (size_t i = 0; i < std::fmin(text.size(), decompText.size()); i++)
  381.     {
  382.         if (text[i] != decompText[i])
  383.         {
  384.             std::cout << i << std::endl;
  385.         }
  386.     }
  387.     writer.write(decompText.c_str(), decompText.size());
  388.  
  389.     return 0;
  390. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement