Advertisement
meta1211

compressor 0.6

Oct 30th, 2018
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.11 KB | None | 0 0
  1. #pragma once
  2. #include <map>
  3. #include <fstream>
  4. #include <string>
  5. #include <iostream>
  6. #define separator ((char)(1))
  7. #define endOfCode ((char)(2))
  8.  
  9. class Compressor
  10. {
  11. public:
  12.  
  13.     static std::string ConvertBitsToString(std::string &bits)
  14.     {
  15.         std::string word;
  16.         unsigned char symbol = ' ';
  17.         int mask = 0;
  18.         for (auto bit: bits)
  19.         {
  20.             if (!mask)
  21.             {
  22.                 word.push_back(symbol);
  23.                 mask = 1 << 7;
  24.                 symbol |= mask;
  25.                 mask >>= 1;
  26.             }
  27.             if (bit == '1')
  28.             {
  29.                     symbol = symbol | mask;
  30.             }
  31.             else
  32.             {
  33.                 symbol = symbol & (~mask);
  34.             }
  35.             mask >>= 1;
  36.         }
  37.         return word;
  38.     }
  39.  
  40.     static inline bool IsGoodSymbol(char symbol)
  41.     {
  42.         return
  43.             symbol != '\n' && symbol != '\t' && symbol != ' ' &&
  44.             symbol != ';' && symbol != ':' && symbol != '.' &&
  45.             symbol != ',' && symbol != '"' && symbol != '<' &&
  46.             symbol != '>' && symbol != '?' && symbol != ',' &&
  47.             symbol != '/' && symbol != '\\' && symbol != '-' &&
  48.             symbol != '+' && symbol != '='  && symbol != '*' &&
  49.             symbol != '%' && symbol != '!' && symbol != '#' &&
  50.             symbol != '~' && symbol != '&' && symbol != '{'&&
  51.             symbol != '}' && symbol != '[' && symbol != ']'&&
  52.             symbol != '|' && symbol != '^' && symbol != '\''&&
  53.             symbol != '(' && symbol != ')' && (symbol < '0' ||
  54.             symbol > '9');
  55.     }
  56.  
  57.     static std::map<std::string, int> CountWords(std::string path)
  58.     {
  59.         std::ifstream file;
  60.         try
  61.         {
  62.             file.open(path);
  63.         }
  64.         catch (const std::exception&)
  65.         {
  66.             throw std::exception("File doesnt exist!");
  67.         }
  68.         std::map<std::string, int> Words;
  69.         std::string curentWord;
  70.         char symbol = 's';
  71.         while (!file.eof())
  72.         {
  73.             while (IsGoodSymbol(symbol) && !file.eof())
  74.             {
  75.                 curentWord.push_back(symbol);
  76.                 file.get(symbol);
  77.             }
  78.             if (curentWord.length() == 0)
  79.             {
  80.                 curentWord.push_back(symbol);
  81.                 file.get(symbol);
  82.             }
  83.             Words[curentWord]++;
  84.             curentWord.clear();
  85.         }
  86.         file.close();
  87.         return Words;
  88.     }
  89.  
  90.     static std::map<std::string, std::string> BulidBinarCode(std::map<std::string, int> words)
  91.     {
  92.         std::map<std::string, std::string> code;
  93.         std::string curentCode("1");
  94.         while (!words.empty())
  95.         {
  96.             std::pair<std::string, int> max;
  97.             for (auto e : words)
  98.             {
  99.                 if (e.second > max.second)
  100.                 {
  101.                     max = e;
  102.                 }
  103.             }
  104.  
  105.             words.erase(max.first);
  106.             code[max.first] = curentCode;
  107.             curentCode += "0";
  108.         }
  109.         return code;
  110.     }
  111.  
  112.     static std::pair<std::string, int> *FindMax(std::map<std::string, int> &words)
  113.     {
  114.         std::pair<std::string, int> *max = new std::pair<std::string, int>("",0);
  115.         for (auto e : words)
  116.         {
  117.             if (e.second > max->second)
  118.             {
  119.                 *max = e;
  120.             }
  121.         }
  122.         return max;
  123.     }
  124.  
  125.     static std::map<std::string, std::string> BulidSymbolCode(std::map<std::string, int> words)
  126.     {
  127.         std::map<std::string, std::string> code;
  128.         std::string curentCode;
  129.         curentCode.push_back('A');
  130.         char curentSymbol = 'B';
  131.         while (!words.empty())
  132.         {
  133.             auto max = FindMax(words);
  134.             words.erase(max->first);
  135.             code[max->first] = curentCode + curentSymbol;
  136.             curentSymbol++;
  137.             if (curentSymbol == 'Z' + 1)
  138.             {
  139.  
  140.                 curentCode.push_back('A');
  141.                 curentSymbol = 'B';
  142.             }
  143.             delete max;
  144.         }
  145.         return code;
  146.     }
  147.  
  148.     static std::map<std::string, std::string> ReadCode(std::string path)
  149.     {
  150.         static std::map<std::string, std::string>Code;
  151.         std::ifstream file(path);
  152.         char symbol;
  153.         std::string word;
  154.         std::string code;
  155.         while (true)
  156.         {
  157.             file.get(symbol);
  158.             if (symbol == endOfCode)
  159.             {
  160.                 break;
  161.             }
  162.             while (symbol != separator)
  163.             {
  164.                 word.push_back(symbol);
  165.                 file.get(symbol);
  166.             }
  167.             file.get(symbol);
  168.             while (symbol != separator)
  169.             {
  170.                 code.push_back(symbol);
  171.                 file.get(symbol);
  172.             }
  173.             Code[word] = code;
  174.             word.clear();
  175.             code.clear();
  176.         }
  177.         file.close();
  178.         return Code;
  179.     }
  180.  
  181.     static void ZipFile(std::string input, std::string output)
  182.     {
  183.         auto words = CountWords(input);
  184.         auto code = BulidSymbolCode(words);
  185.         std::ifstream file(input);
  186.         std::ofstream outputFile(output);
  187.         char symbol;
  188.         std::string curentWord;
  189.         for (auto e : code)
  190.         {
  191.             outputFile << e.second.c_str() << separator << e.first.c_str() << separator;
  192.         }
  193.         outputFile << endOfCode;
  194.         file.get(symbol);
  195.         while (!file.eof())
  196.         {
  197.             while (IsGoodSymbol(symbol) && !file.eof())
  198.             {
  199.                 curentWord.push_back(symbol);
  200.                 file.get(symbol);
  201.             }
  202.             if (curentWord.length() == 0 && !IsGoodSymbol(symbol))
  203.             {
  204.                 curentWord.push_back(symbol);
  205.                 file.get(symbol);
  206.             }
  207.             outputFile << code[curentWord].c_str();
  208.             curentWord.clear();
  209.         }
  210.         file.close();
  211.         outputFile.close();
  212.     }
  213.  
  214.     static void UnZipFile(std::string path, std::string output)
  215.     {
  216.         auto code = ReadCode(path);
  217.         std::ifstream file(path);
  218.         std::ofstream outputFile(output);
  219.         std::string word;
  220.         while (file.peek() != endOfCode)
  221.         {
  222.             file.get();
  223.         }
  224.         file.get();
  225.         char symbol;
  226.         int lastIndex;
  227.         file.get(symbol);
  228.         while (!file.eof())
  229.         {
  230.             word.clear();
  231.             while (symbol == 'A' && !file.eof())
  232.             {
  233.                 word.push_back(symbol);
  234.                 file.get(symbol);
  235.             }
  236.             word.push_back(symbol);
  237.             file.get(symbol);
  238.             outputFile << code[word];
  239.         }
  240.     }
  241. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement